CMake: improve ncurses detection; separate TINFO_LIBRARY input

I found that on macOS, setting the libncurses.a and libtinfo.a into the
same CURSES_LIBRARY variable does not find or link with libtinfo.a.

To fix this, this commit adds a separate TINFO_LIBRARY variable.
In the end, CURSES_LIBRARIES and the Curses::curses CMake TARGET will
still have both libraries set, if both are provided.

This fix is necessary if the ncurses was built with `--with-terminfo`.
I think we got away without it on Linux because of pkg-config.

I also found that Apple's ncurses is prioritized by PkgConfig over one
specified by using variables. To this end, we'll skip PkgConfig if
the include path was provided.
This commit is contained in:
Val Snyder 2024-09-01 12:26:38 -04:00 committed by Val S.
parent 9198f411d5
commit af6d3e85ec
No known key found for this signature in database
GPG key ID: 3A7D293D8274CA1B
4 changed files with 113 additions and 80 deletions

View file

@ -157,12 +157,14 @@ set(CMAKE_SYSROOT /opt/aarch64-wrs-linux-sysroot)
#set(PCRE2_INCLUDE_DIR "/usr/include/") #set(PCRE2_INCLUDE_DIR "/usr/include/")
#set(PCRE2_LIBRARY "/usr/lib64/libpcre2-8.so") #set(PCRE2_LIBRARY "/usr/lib64/libpcre2-8.so")
#set(CURSES_INCLUDE_DIR "/usr/include/") set(NCURSES_INCLUDE_DIR "/usr/include/")
#set(CURSES_LIBRARY "/usr/lib/aarch64-linux-gnu/libncurses.a;/usr/lib/aarch64-linux-gnu/libtinfo.a") set(CURSES_LIBRARY "/usr/lib/aarch64-linux-gnu/libncurses.a")
# Tip: You may not need to also link with libtinfo.a, depending on what your distribution provides: set(TINFO_LIBRARY "/usr/lib/aarch64-linux-gnu/libtinfo.a")
#set(CURSES_LIBRARY "/usr/lib/aarch64-linux-gnu/libncurses.a") # Tip: You may not need to also link with libtinfo.a, depending on what your distribution provides.
# Tip: Alternatively, you could link with the shared library:
# Tip 2: Alternatively, you could link with the shared libraries:
#set(CURSES_LIBRARY "/usr/lib/aarch64-linux-gnu/libncurses.so") #set(CURSES_LIBRARY "/usr/lib/aarch64-linux-gnu/libncurses.so")
#set(TINFO_LIBRARY "/usr/lib/aarch64-linux-gnu/libtinfo.so")
#set(ZLIB_INCLUDE_DIR "/usr/include/") #set(ZLIB_INCLUDE_DIR "/usr/include/")
#set(ZLIB_LIBRARY "/usr/lib64/libz.so") #set(ZLIB_LIBRARY "/usr/lib64/libz.so")
@ -225,12 +227,14 @@ set(LIBXML2_LIBRARY "/usr/lib/aarch64-linux-gnu/libxml2.so")
set(PCRE2_INCLUDE_DIR "/usr/include/") set(PCRE2_INCLUDE_DIR "/usr/include/")
set(PCRE2_LIBRARY "/usr/lib/aarch64-linux-gnu/libpcre2-8.so") set(PCRE2_LIBRARY "/usr/lib/aarch64-linux-gnu/libpcre2-8.so")
set(CURSES_INCLUDE_DIR "/usr/include/") set(NCURSES_INCLUDE_DIR "/usr/include/")
set(CURSES_LIBRARY "/usr/lib/aarch64-linux-gnu/libncurses.a;/usr/lib/aarch64-linux-gnu/libtinfo.a") set(CURSES_LIBRARY "/usr/lib/aarch64-linux-gnu/libncurses.a")
# Tip: You may not need to also link with libtinfo.a, depending on what your distribution provides: set(TINFO_LIBRARY "/usr/lib/aarch64-linux-gnu/libtinfo.a")
#set(CURSES_LIBRARY "/usr/lib/aarch64-linux-gnu/libncurses.a") # Tip: You may not need to also link with libtinfo.a, depending on what your distribution provides.
# Tip: Alternatively, you could link with the shared library:
# Tip 2: Alternatively, you could link with the shared libraries:
#set(CURSES_LIBRARY "/usr/lib/aarch64-linux-gnu/libncurses.so") #set(CURSES_LIBRARY "/usr/lib/aarch64-linux-gnu/libncurses.so")
#set(TINFO_LIBRARY "/usr/lib/aarch64-linux-gnu/libtinfo.so")
set(ZLIB_INCLUDE_DIR "/usr/include/") set(ZLIB_INCLUDE_DIR "/usr/include/")
set(ZLIB_LIBRARY "/usr/lib/aarch64-linux-gnu/libz.so") set(ZLIB_LIBRARY "/usr/lib/aarch64-linux-gnu/libz.so")

View file

@ -675,6 +675,11 @@ and:
-D CURSES_LIBRARY="_filepath of curses library_" -D CURSES_LIBRARY="_filepath of curses library_"
``` ```
and, if tinfo is separate from ncurses:
```sh
-D TINFO_LIBRARY="_filepath of tinfo library_"
```
### Bytecode Runtime ### Bytecode Runtime
Bytecode signatures are a type of executable plugin that provide extra Bytecode signatures are a type of executable plugin that provide extra

5
Jenkinsfile vendored
View file

@ -99,8 +99,9 @@ pipeline {
-D LIBXML2_LIBRARY="$HOME/.mussels/install/host-static/lib/libxml2.a" \ -D LIBXML2_LIBRARY="$HOME/.mussels/install/host-static/lib/libxml2.a" \
-D PCRE2_INCLUDE_DIR="$HOME/.mussels/install/host-static/include" \ -D PCRE2_INCLUDE_DIR="$HOME/.mussels/install/host-static/include" \
-D PCRE2_LIBRARY="$HOME/.mussels/install/host-static/lib/libpcre2-8.a" \ -D PCRE2_LIBRARY="$HOME/.mussels/install/host-static/lib/libpcre2-8.a" \
-D CURSES_INCLUDE_DIR="$HOME/.mussels/install/host-static/include" \ -D NCURSES_INCLUDE_DIR="$HOME/.mussels/install/host-static/include" \
-D CURSES_LIBRARY="$HOME/.mussels/install/host-static/lib/libncurses.a;$HOME/.mussels/install/host-static/lib/libtinfo.a" \ -D CURSES_LIBRARY="$HOME/.mussels/install/host-static/lib/libncurses.a" \
-D TINFO_LIBRARY="$HOME/.mussels/install/host-static/lib/libtinfo.a" \
-D ZLIB_INCLUDE_DIR="$HOME/.mussels/install/host-static/include" \ -D ZLIB_INCLUDE_DIR="$HOME/.mussels/install/host-static/include" \
-D ZLIB_LIBRARY="$HOME/.mussels/install/host-static/lib/libz.a" \ -D ZLIB_LIBRARY="$HOME/.mussels/install/host-static/lib/libz.a" \
-D LIBCHECK_INCLUDE_DIR="$HOME/.mussels/install/host-static/include" \ -D LIBCHECK_INCLUDE_DIR="$HOME/.mussels/install/host-static/include" \

View file

@ -13,7 +13,7 @@ Imported Targets
This module provides the following imported targets, if found: This module provides the following imported targets, if found:
``Curses::curses`` ``Curses::curses``
The CURSES library The CURSES library and possibly TINFO library
Result Variables Result Variables
^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^
@ -34,20 +34,26 @@ Cache Variables
The following cache variables may also be set: The following cache variables may also be set:
``CURSES_INCLUDE_DIR`` ``NCURSES_INCLUDE_DIR``
The directory containing ``foo.h``. The directory containing ``ncurses.h``.
``PDCURSES_INCLUDE_DIR``
The directory containing ``curses.h``.
``CURSES_LIBRARY`` ``CURSES_LIBRARY``
The path to the CURSES library. The path to the CURSES library.
``TINFO_LIBRARY``
The path to the TINFO library.
#]=======================================================================] #]=======================================================================]
find_package(PkgConfig QUIET) if(NOT NCURSES_INCLUDE_DIR)
# First try for NCurses find_package(PkgConfig QUIET)
pkg_search_module (PC_NCurses QUIET ncurses ncursesw) # First try for NCurses
pkg_search_module (PC_NCurses QUIET ncurses ncursesw)
endif()
find_path(NCURSES_INCLUDE_DIR find_path(NCURSES_INCLUDE_DIR
NAMES ncurses.h NAMES ncurses.h
PATHS ${PC_NCurses_INCLUDE_DIRS} ${CURSES_INCLUDE_DIR} PATHS ${PC_NCurses_INCLUDE_DIRS} ${CURSES_INCLUDE_DIR}
) )
string(FIND ${NCURSES_INCLUDE_DIR} "-NOTFOUND" NCURSES_NOT_FOUND) string(FIND ${NCURSES_INCLUDE_DIR} "-NOTFOUND" NCURSES_NOT_FOUND)
@ -69,82 +75,99 @@ if(NCURSES_NOT_FOUND EQUAL -1)
include(FindPackageHandleStandardArgs) include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(CURSES find_package_handle_standard_args(CURSES
FOUND_VAR CURSES_FOUND FOUND_VAR CURSES_FOUND
REQUIRED_VARS REQUIRED_VARS
CURSES_LIBRARY CURSES_LIBRARY
NCURSES_INCLUDE_DIR NCURSES_INCLUDE_DIR
VERSION_VAR CURSES_VERSION VERSION_VAR CURSES_VERSION
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(TINFO
FOUND_VAR TINFO_FOUND
REQUIRED_VARS
TINFO_LIBRARY
NCURSES_INCLUDE_DIR
VERSION_VAR CURSES_VERSION
NAME_MISMATCHED
) )
set(HAVE_LIBNCURSES 1) set(HAVE_LIBNCURSES 1)
set(CURSES_INCLUDE "<ncurses.h>") set(CURSES_INCLUDE "<ncurses.h>")
set(CURSES_LIBRARIES ${CURSES_LIBRARY}) if(NOT TINFO_FOUND)
set(CURSES_LIBRARIES "${CURSES_LIBRARY}")
else()
set(CURSES_LIBRARIES "${CURSES_LIBRARY};${TINFO_LIBRARY}")
endif()
set(CURSES_INCLUDE_DIRS ${NCURSES_INCLUDE_DIR}) set(CURSES_INCLUDE_DIRS ${NCURSES_INCLUDE_DIR})
set(CURSES_DEFINITIONS ${PC_NCurses_CFLAGS_OTHER}) set(CURSES_DEFINITIONS ${PC_NCurses_CFLAGS_OTHER})
if (NOT TARGET Curses::curses) if (NOT TARGET Curses::curses)
add_library(Curses::curses INTERFACE IMPORTED) add_library(Curses::curses INTERFACE IMPORTED)
set_target_properties(Curses::curses PROPERTIES set_target_properties(Curses::curses PROPERTIES
INTERFACE_COMPILE_OPTIONS "${PC_NCurses_CFLAGS_OTHER}" INTERFACE_COMPILE_OPTIONS "${PC_NCurses_CFLAGS_OTHER}"
INTERFACE_INCLUDE_DIRECTORIES "${CURSES_INCLUDE_DIRS}" INTERFACE_INCLUDE_DIRECTORIES "${CURSES_INCLUDE_DIRS}"
INTERFACE_LINK_LIBRARIES "${CURSES_LIBRARY}" INTERFACE_LINK_LIBRARIES "${CURSES_LIBRARIES}"
) )
endif() endif()
else() else()
# Try for PDCurses # Try for PDCurses
pkg_check_modules(PC_PDCurses QUIET curses) pkg_check_modules(PC_PDCurses QUIET curses)
find_path(PDCURSES_INCLUDE_DIR find_path(PDCURSES_INCLUDE_DIR
NAMES curses.h NAMES curses.h
PATHS ${PC_PDCurses_INCLUDE_DIRS} ${CURSES_INCLUDE_DIR} PATHS ${PC_PDCurses_INCLUDE_DIRS} ${CURSES_INCLUDE_DIR}
) )
string(FIND ${PDCURSES_INCLUDE_DIR} "-NOTFOUND" PDCURSES_NOT_FOUND) string(FIND ${PDCURSES_INCLUDE_DIR} "-NOTFOUND" PDCURSES_NOT_FOUND)
if(PDCURSES_NOT_FOUND EQUAL -1) if(PDCURSES_NOT_FOUND EQUAL -1)
# #
# pdcurses WAS found! # pdcurses WAS found!
# #
set(HAVE_LIBPDCURSES 1) set(HAVE_LIBPDCURSES 1)
set(CURSES_INCLUDE "<curses.h>") set(CURSES_INCLUDE "<curses.h>")
find_library(CURSES_LIBRARY find_library(CURSES_LIBRARY
NAMES curses pdcurses NAMES curses pdcurses
PATHS ${PC_PDCurses_LIBRARY_DIRS} PATHS ${PC_PDCurses_LIBRARY_DIRS}
)
set(CURSES_VERSION ${PC_PDCurses_VERSION})
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(CURSES
FOUND_VAR CURSES_FOUND
REQUIRED_VARS
CURSES_LIBRARY
PDCURSES_INCLUDE_DIR
VERSION_VAR CURSES_VERSION
)
set(HAVE_LIBPDCURSES 1)
set(CURSES_INCLUDE "<curses.h>")
set(CURSES_LIBRARIES ${CURSES_LIBRARY})
set(CURSES_INCLUDE_DIRS ${PDCURSES_INCLUDE_DIR})
set(CURSES_DEFINITIONS ${PC_PDCurses_CFLAGS_OTHER})
if (NOT TARGET Curses::curses)
add_library(Curses::curses UNKNOWN IMPORTED)
set_target_properties(Curses::curses PROPERTIES
INTERFACE_COMPILE_OPTIONS "${PC_PDCurses_CFLAGS_OTHER}"
INTERFACE_INCLUDE_DIRECTORIES "${CURSES_INCLUDE_DIRS}"
IMPORTED_LOCATION "${CURSES_LIBRARY}"
) )
endif()
else() set(CURSES_VERSION ${PC_PDCurses_VERSION})
message(FATAL_ERROR "Unable to find ncurses or pdcurses")
endif() include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(CURSES
FOUND_VAR CURSES_FOUND
REQUIRED_VARS
CURSES_LIBRARY
PDCURSES_INCLUDE_DIR
VERSION_VAR CURSES_VERSION
)
set(HAVE_LIBPDCURSES 1)
set(CURSES_INCLUDE "<curses.h>")
set(CURSES_LIBRARIES ${CURSES_LIBRARY})
set(CURSES_INCLUDE_DIRS ${PDCURSES_INCLUDE_DIR})
set(CURSES_DEFINITIONS ${PC_PDCurses_CFLAGS_OTHER})
if (NOT TARGET Curses::curses)
add_library(Curses::curses UNKNOWN IMPORTED)
set_target_properties(Curses::curses PROPERTIES
INTERFACE_COMPILE_OPTIONS "${PC_PDCurses_CFLAGS_OTHER}"
INTERFACE_INCLUDE_DIRECTORIES "${CURSES_INCLUDE_DIRS}"
IMPORTED_LOCATION "${CURSES_LIBRARIES}"
)
endif()
else()
message(FATAL_ERROR "Unable to find ncurses or pdcurses")
endif()
endif() endif()
mark_as_advanced( mark_as_advanced(
CURSES_INCLUDE_DIR NCURSES_INCLUDE_DIR
CURSES_LIBRARY PDCURSES_INCLUDE_DIR
CURSES_LIBRARY
TINFO_LIBRARY
) )