Skip to content

Commit 0ee6302

Browse files
authored
Modernise FindReadline.cmake, and fix on Solaris (#813)
The CMake build fails on Solaris out of the box. * Fix Solaris vanilla CMake build; remove CI override that forces use of termcap. * Move up pcre2_use_system_extensions to the top of CMakeLists.txt * Use cmake_push_check_state() instead of manual management of state * Move _GNU_SOURCE detection into pcre2_use_system_extensions, to match Autoconf
1 parent c5ad23c commit 0ee6302

File tree

6 files changed

+170
-82
lines changed

6 files changed

+170
-82
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,7 @@ jobs:
420420
echo "== CMake, 64-bit =="
421421
cd ../build-cmake-64
422422
423-
CC="cc -m64" cmake $CMAKE_FLAGS -DNCURSES_LIBRARY=termcap -DPCRE2_BUILD_PCRE2_16=ON -DPCRE2_BUILD_PCRE2_32=ON -DBUILD_SHARED_LIBS=ON -DBUILD_STATIC_LIBS=ON -DPCRE2_DEBUG=ON -DCMAKE_C_FLAGS="$CFLAGS_SOLARIS_CC" -DCMAKE_COMPILE_WARNING_AS_ERROR=ON -DCMAKE_BUILD_TYPE=Release -B build
423+
CC="cc -m64" cmake $CMAKE_FLAGS -DPCRE2_BUILD_PCRE2_16=ON -DPCRE2_BUILD_PCRE2_32=ON -DBUILD_SHARED_LIBS=ON -DBUILD_STATIC_LIBS=ON -DPCRE2_DEBUG=ON -DCMAKE_C_FLAGS="$CFLAGS_SOLARIS_CC" -DCMAKE_COMPILE_WARNING_AS_ERROR=ON -DCMAKE_BUILD_TYPE=Release -B build
424424
cd build
425425
make
426426
ctest -j3 --output-on-failure

CMakeLists.txt

Lines changed: 63 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ include(CheckSymbolExists)
161161
include(CheckIncludeFile)
162162
include(CheckTypeSize)
163163
include(CMakePackageConfigHelpers)
164+
include(CMakePushCheckState)
164165
include(GNUInstallDirs) # for CMAKE_INSTALL_LIBDIR
165166
include(PCRE2CheckLinkerFlag)
166167
include(PCRE2UseSystemExtensions)
@@ -172,8 +173,25 @@ check_include_file(sys/types.h HAVE_SYS_TYPES_H)
172173
check_include_file(unistd.h HAVE_UNISTD_H)
173174
check_include_file(windows.h HAVE_WINDOWS_H)
174175

175-
check_symbol_exists(memfd_create "sys/mman.h" HAVE_MEMFD_CREATE)
176-
check_symbol_exists(secure_getenv "stdlib.h" HAVE_SECURE_GETENV)
176+
# Check whether any system-wide extensions need to be enabled, in order for
177+
# OS functionality to be exposed.
178+
pcre2_use_system_extensions()
179+
180+
cmake_push_check_state(RESET)
181+
# Somewhat awkward code to propagate the _GNU_SOURCE definition (added to
182+
# COMPILE_DEFINITIONS by pcre2_use_system_extensions()).
183+
get_directory_property(_pcre2_compile_definitions COMPILE_DEFINITIONS)
184+
if(DEFINED _pcre2_compile_definitions)
185+
set(CMAKE_REQUIRED_DEFINITIONS "")
186+
foreach(_def IN LISTS _pcre2_compile_definitions)
187+
list(APPEND CMAKE_REQUIRED_DEFINITIONS "-D${_def}")
188+
endforeach()
189+
endif()
190+
191+
check_symbol_exists(mkostemp stdlib.h HAVE_MKOSTEMP) # glibc 2.7
192+
check_symbol_exists(memfd_create "sys/mman.h" HAVE_MEMFD_CREATE) # glibc 2.27
193+
check_symbol_exists(secure_getenv "stdlib.h" HAVE_SECURE_GETENV) # glibc 2.17
194+
cmake_pop_check_state()
177195

178196
check_c_source_compiles(
179197
[=[
@@ -184,10 +202,10 @@ check_c_source_compiles(
184202
HAVE_REALPATH
185203
)
186204

205+
cmake_push_check_state()
187206
if(NOT DEFINED CMAKE_REQUIRED_FLAGS)
188207
set(CMAKE_REQUIRED_FLAGS "")
189208
endif()
190-
set(ORIG_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
191209
if(NOT MSVC AND NOT CMAKE_C_COMPILER_ID STREQUAL "XL" AND NOT CMAKE_C_COMPILER_ID STREQUAL "SunPro")
192210
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Werror")
193211
endif()
@@ -197,6 +215,7 @@ check_c_source_compiles(
197215
HAVE_ATTRIBUTE_UNINITIALIZED
198216
)
199217

218+
# TODO Consider switching to modern "GenerateExportHeader"
200219
check_c_source_compiles(
201220
[=[
202221
extern __attribute__ ((visibility ("default"))) int f(void);
@@ -206,14 +225,14 @@ check_c_source_compiles(
206225
HAVE_VISIBILITY
207226
)
208227

228+
cmake_pop_check_state()
229+
209230
if(HAVE_VISIBILITY)
210231
set(PCRE2_EXPORT [=[__attribute__ ((visibility ("default")))]=])
211232
else()
212233
set(PCRE2_EXPORT)
213234
endif()
214235

215-
set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})
216-
217236
check_c_source_compiles("int main(void) { __assume(1); return 0; }" HAVE_BUILTIN_ASSUME)
218237

219238
check_c_source_compiles(
@@ -271,11 +290,6 @@ if(INTEL_CET_ENABLED)
271290
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mshstk")
272291
endif()
273292

274-
# Check whether any system-wide extensions need to be enabled, in order for
275-
# OS functionality to be exposed.
276-
277-
pcre2_use_system_extensions()
278-
279293
# User-configurable options
280294
#
281295
# Note: CMakeSetup displays these in alphabetical order, regardless of
@@ -436,32 +450,45 @@ if(BZIP2_FOUND)
436450
option(PCRE2_SUPPORT_LIBBZ2 "Enable support for linking pcre2grep with libbz2." ON)
437451
endif()
438452
if(PCRE2_SUPPORT_LIBBZ2)
439-
include_directories(${BZIP2_INCLUDE_DIR})
453+
if(BZIP2_FOUND)
454+
include_directories(${BZIP2_INCLUDE_DIR})
455+
else()
456+
message(
457+
FATAL_ERROR
458+
" libbz2 not found. Set BZIP2_INCLUDE_DIR to a compatible header\n"
459+
" or set BZip2_ROOT to a full bzip2 installed tree, as needed."
460+
)
461+
endif()
440462
endif()
441463

442464
# zlib
443465
if(ZLIB_FOUND)
444466
option(PCRE2_SUPPORT_LIBZ "Enable support for linking pcre2grep with libz." ON)
445467
endif()
446468
if(PCRE2_SUPPORT_LIBZ)
447-
include_directories(${ZLIB_INCLUDE_DIR})
469+
if(ZLIB_FOUND)
470+
include_directories(${ZLIB_INCLUDE_DIR})
471+
else()
472+
message(
473+
FATAL_ERROR
474+
" zlib not found. Set ZLIB_INCLUDE_DIR to a compatible header\n"
475+
" or set ZLIB_ROOT to a full zlib installed tree, as needed."
476+
)
477+
endif()
448478
endif()
449479

450480
# editline lib
451481
if(EDITLINE_FOUND)
452482
option(PCRE2_SUPPORT_LIBEDIT "Enable support for linking pcre2test with libedit." OFF)
453483
endif()
454-
if(EDITLINE_FOUND)
455-
if(PCRE2_SUPPORT_LIBEDIT)
484+
if(PCRE2_SUPPORT_LIBEDIT)
485+
if(EDITLINE_FOUND)
456486
include_directories(${EDITLINE_INCLUDE_DIR})
457-
endif()
458-
else()
459-
if(PCRE2_SUPPORT_LIBEDIT)
487+
else()
460488
message(
461489
FATAL_ERROR
462-
" libedit not found, set EDITLINE_INCLUDE_DIR to a compatible header\n"
463-
" or set Editline_ROOT to a full libedit installed tree, as needed\n"
464-
" Might need to enable policy CMP0074 in CMakeLists.txt"
490+
" libedit not found. Set EDITLINE_INCLUDE_DIR to a compatible header\n"
491+
" or set Editline_ROOT to a full libedit installed tree, as needed."
465492
)
466493
endif()
467494
endif()
@@ -471,7 +498,15 @@ if(READLINE_FOUND)
471498
option(PCRE2_SUPPORT_LIBREADLINE "Enable support for linking pcre2test with libreadline." ON)
472499
endif()
473500
if(PCRE2_SUPPORT_LIBREADLINE)
474-
include_directories(${READLINE_INCLUDE_DIR})
501+
if(READLINE_FOUND)
502+
include_directories(${READLINE_INCLUDE_DIR})
503+
else()
504+
message(
505+
FATAL_ERROR
506+
" libreadline not found. Set READLINE_INCLUDE_DIR to a compatible header\n"
507+
" or set Readline_ROOT to a full libreadline installed tree, as needed."
508+
)
509+
endif()
475510
endif()
476511

477512
# Prepare build configuration
@@ -537,19 +572,7 @@ if(PCRE2_SUPPORT_JIT)
537572
endif()
538573

539574
if(PCRE2_SUPPORT_JIT_SEALLOC)
540-
set(CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE)
541-
check_symbol_exists(mkostemp stdlib.h REQUIRED)
542-
unset(CMAKE_REQUIRED_DEFINITIONS)
543-
if(${REQUIRED})
544-
if(${CMAKE_SYSTEM_NAME} MATCHES Linux|NetBSD)
545-
add_compile_definitions(_GNU_SOURCE)
546-
set(SLJIT_PROT_EXECUTABLE_ALLOCATOR 1)
547-
else()
548-
message(FATAL_ERROR "Your configuration is not supported")
549-
endif()
550-
else()
551-
set(PCRE2_SUPPORT_JIT_SEALLOC OFF)
552-
endif()
575+
set(SLJIT_PROT_EXECUTABLE_ALLOCATOR 1)
553576
endif()
554577

555578
if(PCRE2GREP_SUPPORT_JIT)
@@ -1491,7 +1514,12 @@ if(PCRE2_SHOW_REPORT)
14911514
endforeach()
14921515
else()
14931516
string(TOUPPER "${CMAKE_BUILD_TYPE}" buildtype)
1494-
message(STATUS " C compiler flags .................. : ${CMAKE_C_FLAGS}${CFSP}${CMAKE_C_FLAGS_${buildtype}}")
1517+
if(buildtype STREQUAL "")
1518+
set(CFBLD "")
1519+
else()
1520+
set(CFBLD "${CMAKE_C_FLAGS_${buildtype}}")
1521+
endif()
1522+
message(STATUS " C compiler flags .................. : ${CMAKE_C_FLAGS}${CFSP}${CFBLD}")
14951523
endif()
14961524

14971525
message(STATUS "")

cmake/FindEditline.cmake

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
# Modified from FindReadline.cmake (PH Feb 2012)
22

3-
if(EDITLINE_INCLUDE_DIR AND EDITLINE_LIBRARY)
4-
set(EDITLINE_FOUND TRUE)
5-
else()
6-
find_path(EDITLINE_INCLUDE_DIR readline.h PATH_SUFFIXES editline edit/readline)
3+
find_path(EDITLINE_INCLUDE_DIR readline.h PATH_SUFFIXES editline edit/readline)
4+
mark_as_advanced(EDITLINE_INCLUDE_DIR)
75

8-
find_library(EDITLINE_LIBRARY NAMES edit)
9-
include(FindPackageHandleStandardArgs)
10-
find_package_handle_standard_args(Editline DEFAULT_MSG EDITLINE_INCLUDE_DIR EDITLINE_LIBRARY)
6+
find_library(EDITLINE_LIBRARY NAMES edit)
7+
mark_as_advanced(EDITLINE_LIBRARY)
118

12-
mark_as_advanced(EDITLINE_INCLUDE_DIR EDITLINE_LIBRARY)
13-
endif()
9+
include(FindPackageHandleStandardArgs)
10+
find_package_handle_standard_args(Editline DEFAULT_MSG EDITLINE_LIBRARY EDITLINE_INCLUDE_DIR)

cmake/FindReadline.cmake

Lines changed: 49 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,53 @@
33
# --> BSD licensed
44
#
55
# GNU Readline library finder
6-
if(READLINE_INCLUDE_DIR AND READLINE_LIBRARY AND NCURSES_LIBRARY)
7-
set(READLINE_FOUND TRUE)
8-
else()
9-
find_path(READLINE_INCLUDE_DIR readline/readline.h /usr/include/readline)
10-
11-
# 2008-04-22 The next clause used to read like this:
12-
#
13-
# FIND_LIBRARY(READLINE_LIBRARY NAMES readline)
14-
# FIND_LIBRARY(NCURSES_LIBRARY NAMES ncurses )
15-
# include(FindPackageHandleStandardArgs)
16-
# FIND_PACKAGE_HANDLE_STANDARD_ARGS(Readline DEFAULT_MSG NCURSES_LIBRARY READLINE_INCLUDE_DIR READLINE_LIBRARY )
17-
#
18-
# I was advised to modify it such that it will find an ncurses library if
19-
# required, but not if one was explicitly given, that is, it allows the
20-
# default to be overridden. PH
21-
22-
find_library(READLINE_LIBRARY NAMES readline)
23-
include(FindPackageHandleStandardArgs)
24-
find_package_handle_standard_args(Readline DEFAULT_MSG READLINE_INCLUDE_DIR READLINE_LIBRARY)
25-
26-
mark_as_advanced(READLINE_INCLUDE_DIR READLINE_LIBRARY)
6+
7+
find_path(READLINE_INCLUDE_DIR readline/readline.h PATH_SUFFIXES include)
8+
mark_as_advanced(READLINE_INCLUDE_DIR)
9+
10+
find_library(READLINE_LIBRARY NAMES readline)
11+
mark_as_advanced(READLINE_LIBRARY)
12+
13+
if(READLINE_INCLUDE_DIR AND READLINE_LIBRARY)
14+
# Check if we need to link to ncurses as well
15+
16+
include(CheckSymbolExists)
17+
include(CMakePushCheckState)
18+
19+
cmake_push_check_state(RESET)
20+
set(CMAKE_REQUIRED_LIBRARIES "${READLINE_LIBRARY}")
21+
set(CMAKE_REQUIRED_INCLUDES "${READLINE_INCLUDE_DIR}")
22+
check_symbol_exists("readline" "stdio.h;readline/readline.h" HAVE_READLINE_FUNC)
23+
24+
if(NOT HAVE_READLINE_FUNC)
25+
foreach(
26+
lib IN ITEMS
27+
tinfo
28+
curses
29+
ncurses
30+
ncursesw
31+
termcap
32+
)
33+
find_library(NCURSES_LIBRARY_${lib} NAMES ${lib})
34+
mark_as_advanced(NCURSES_LIBRARY_${lib})
35+
if(NCURSES_LIBRARY_${lib})
36+
cmake_reset_check_state()
37+
set(CMAKE_REQUIRED_LIBRARIES "${READLINE_LIBRARY}" "${NCURSES_LIBRARY_${lib}}")
38+
set(CMAKE_REQUIRED_INCLUDES "${READLINE_INCLUDE_DIR}")
39+
check_symbol_exists("readline" "stdio.h;readline/readline.h" HAVE_READLINE_FUNC_${lib})
40+
41+
if(HAVE_READLINE_FUNC_${lib})
42+
message(STATUS "Looking for readline - readline needs ${lib}")
43+
set(NCURSES_LIBRARY "${NCURSES_LIBRARY_${lib}}" CACHE FILEPATH "Path to the ncurses library")
44+
mark_as_advanced(NCURSES_LIBRARY)
45+
break()
46+
endif()
47+
endif()
48+
endforeach()
49+
endif()
50+
51+
cmake_pop_check_state()
2752
endif()
53+
54+
include(FindPackageHandleStandardArgs)
55+
find_package_handle_standard_args(Readline DEFAULT_MSG READLINE_LIBRARY READLINE_INCLUDE_DIR)

cmake/PCRE2UseSystemExtensions.cmake

Lines changed: 50 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,38 +10,73 @@
1010
# So far, we know that we require:
1111
# - _ALL_SOURCE on IBM systems (z/OS, probably AIX) in order to call
1212
# getrlimit() in pcre2test.
13+
# - _GNU_SOURCE on Linux in order to call mkostemp() in some (non-default)
14+
# configurations of the JIT.
1315
#
1416
# Autoconf enables this unconditionally. However, our CMake script potentially
1517
# supports *more* platforms than Autoconf, so we use a feature check.
1618

1719
function(pcre2_use_system_extensions)
18-
if (WIN32)
20+
if(WIN32)
1921
return()
2022
endif()
2123

24+
include(CheckSymbolExists)
2225
include(CheckCSourceCompiles)
26+
include(CMakePushCheckState)
2327

24-
set(_pcre2_test_src "
25-
#include <sys/time.h>
26-
#include <sys/resource.h>
28+
cmake_push_check_state(RESET)
29+
set(
30+
_pcre2_test_src
31+
[=[
32+
#include <sys/time.h>
33+
#include <sys/resource.h>
2734

28-
int main(void) {
29-
struct rlimit rlim;
30-
getrlimit(RLIMIT_STACK, &rlim);
31-
return 0;
32-
}
33-
")
35+
int main(void) {
36+
struct rlimit rlim;
37+
getrlimit(RLIMIT_STACK, &rlim);
38+
return 0;
39+
}
40+
]=]
41+
)
42+
set(CMAKE_REQUIRED_QUIET TRUE)
43+
check_c_source_compiles("${_pcre2_test_src}" _HAVE_GETRLIMIT_NAKED)
3444

35-
check_c_source_compiles("${_pcre2_test_src}" HAVE_GETRLIMIT)
36-
37-
if (NOT HAVE_GETRLIMIT)
45+
if(NOT _HAVE_GETRLIMIT_NAKED)
3846
# Try again with _ALL_SOURCE
47+
if(NOT _HAVE_GETRLIMIT_ALLSOURCE)
48+
set(_allsource_first_run TRUE)
49+
endif()
3950
set(CMAKE_REQUIRED_DEFINITIONS "-D_ALL_SOURCE")
40-
check_c_source_compiles("${_pcre2_test_src}" HAVE_GETRLIMIT_ALLSOURCE)
51+
check_c_source_compiles("${_pcre2_test_src}" _HAVE_GETRLIMIT_ALLSOURCE)
4152
unset(CMAKE_REQUIRED_DEFINITIONS)
4253

43-
if (HAVE_GETRLIMIT_ALLSOURCE)
54+
if(_HAVE_GETRLIMIT_ALLSOURCE)
4455
add_compile_definitions(_ALL_SOURCE)
56+
if(_allsource_first_run)
57+
message(STATUS "Detected platform feature gate _ALL_SOURCE")
58+
endif()
59+
endif()
60+
endif()
61+
62+
check_symbol_exists(mkostemp stdlib.h _HAVE_MKOSTEMP_NAKED)
63+
64+
if(NOT _HAVE_MKOSTEMP_NAKED)
65+
# Try again with _GNU_SOURCE
66+
if(NOT _HAVE_MKOSTEMP_GNUSOURCE)
67+
set(_gnusource_first_run TRUE)
68+
endif()
69+
set(CMAKE_REQUIRED_DEFINITIONS "-D_GNU_SOURCE")
70+
check_symbol_exists(mkostemp stdlib.h _HAVE_MKOSTEMP_GNUSOURCE)
71+
unset(CMAKE_REQUIRED_DEFINITIONS)
72+
73+
if(_HAVE_MKOSTEMP_GNUSOURCE)
74+
add_compile_definitions(_GNU_SOURCE)
75+
if(_gnusource_first_run)
76+
message(STATUS "Detected platform feature gate _GNU_SOURCE")
77+
endif()
4578
endif()
4679
endif()
80+
81+
cmake_pop_check_state()
4782
endfunction()

configure.ac

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -677,7 +677,7 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([[
677677
AC_MSG_RESULT([no]))
678678
LIBS="$OLD_LIBS"
679679

680-
# Check for the availabiity of libreadline
680+
# Check for the availability of libreadline
681681

682682
if test "$enable_pcre2test_libreadline" = "yes"; then
683683
AC_CHECK_HEADERS([readline/readline.h], [HAVE_READLINE_H=1])

0 commit comments

Comments
 (0)