Skip to content

Commit b60722b

Browse files
authored
Move the linker script detection code out into its own CMake module
1 parent c1acd51 commit b60722b

12 files changed

+252
-133
lines changed

CMakeLists.txt

Lines changed: 53 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -114,12 +114,13 @@
114114
# -- ./CMakeLists.txt ./cmake/*.cmake ./cmake/*.cmake.in
115115
################################################################################
116116

117+
message(STATUS "Using CMake version ${CMAKE_VERSION} (${CMAKE_COMMAND})")
118+
117119
# Increased minimum to 3.15 to allow use of string(REPEAT).
118120
cmake_minimum_required(VERSION 3.15 FATAL_ERROR)
119121
project(PCRE2 C)
120122
set(CMAKE_C_STANDARD 99)
121123
set(CMAKE_C_STANDARD_REQUIRED TRUE)
122-
123124
set(CMAKE_C_VISIBILITY_PRESET hidden)
124125

125126
# Solaris-specific fix for "CMAKE_C_VISIBILITY_PRESET": this feature was only
@@ -141,12 +142,10 @@ endif()
141142
# cmake_policy(SET CMP0026 OLD)
142143
# cmake_policy(SET CMP0074 NEW)
143144

144-
# For FindReadline.cmake. This uses list(APPEND) rather than set() to allow
145+
# For our modules in cmake/. This uses list(APPEND) rather than set() to allow
145146
# setting CMAKE_MODULE_PATH on the command line.
146147
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
147148

148-
include_directories(${PROJECT_BINARY_DIR}/interface ${PROJECT_BINARY_DIR}/src ${PROJECT_SOURCE_DIR}/src)
149-
150149
# external packages
151150
find_package(BZip2)
152151
find_package(ZLIB)
@@ -163,7 +162,7 @@ include(CheckTypeSize)
163162
include(CMakePackageConfigHelpers)
164163
include(CMakePushCheckState)
165164
include(GNUInstallDirs) # for CMAKE_INSTALL_LIBDIR
166-
include(PCRE2CheckLinkerFlag)
165+
include(PCRE2CheckVscript)
167166
include(PCRE2UseSystemExtensions)
168167
include(PCRE2WarningAsError)
169168

@@ -270,29 +269,7 @@ check_c_source_compiles(
270269

271270
# Detect support for linker scripts.
272271

273-
file(WRITE ${PROJECT_BINARY_DIR}/test-map-file.sym "PCRE2_10.00 { global: main; };")
274-
file(WRITE ${PROJECT_BINARY_DIR}/test-map-file-broken.sym "PCRE2_10.00 { global: main; }; {")
275-
if(NOT MSVC)
276-
pcre2_check_linker_flag(C -Wl,--version-script,${PROJECT_BINARY_DIR}/test-map-file.sym HAVE_VSCRIPT_GNU)
277-
pcre2_check_linker_flag(C -Wl,-M,${PROJECT_BINARY_DIR}/test-map-file.sym HAVE_VSCRIPT_SUN)
278-
endif()
279-
if(HAVE_VSCRIPT_GNU)
280-
set(VSCRIPT_FLAG --version-script)
281-
set(HAVE_VSCRIPT TRUE)
282-
elseif(HAVE_VSCRIPT_SUN)
283-
set(VSCRIPT_FLAG -M)
284-
set(HAVE_VSCRIPT TRUE)
285-
endif()
286-
if(HAVE_VSCRIPT)
287-
# Perform the same logic as ax_check_vscript.m4, to test whether the linker
288-
# silently ignores (and overwrites) linker scripts it doesn't understand.
289-
pcre2_check_linker_flag(C -Wl,${VSCRIPT_FLAG},${PROJECT_BINARY_DIR}/test-map-file-broken.sym HAVE_VSCRIPT_BROKEN)
290-
if(HAVE_VSCRIPT_BROKEN)
291-
set(HAVE_VSCRIPT FALSE)
292-
endif()
293-
endif()
294-
file(REMOVE ${PROJECT_BINARY_DIR}/test-map-file.sym)
295-
file(REMOVE ${PROJECT_BINARY_DIR}/test-map-file-broken.sym)
272+
pcre2_check_vscript(HAVE_VSCRIPT VSCRIPT_FLAG)
296273

297274
# Check whether Intel CET is enabled, and if so, adjust compiler flags. This
298275
# code was written by PH, trying to imitate the logic from the autotools
@@ -472,6 +449,54 @@ endif()
472449
if(BZIP2_FOUND)
473450
option(PCRE2_SUPPORT_LIBBZ2 "Enable support for linking pcre2grep with libbz2." ON)
474451
endif()
452+
453+
# zlib
454+
if(ZLIB_FOUND)
455+
option(PCRE2_SUPPORT_LIBZ "Enable support for linking pcre2grep with libz." ON)
456+
endif()
457+
458+
# editline lib
459+
if(EDITLINE_FOUND)
460+
option(PCRE2_SUPPORT_LIBEDIT "Enable support for linking pcre2test with libedit." OFF)
461+
endif()
462+
463+
# readline lib
464+
if(READLINE_FOUND)
465+
option(PCRE2_SUPPORT_LIBREADLINE "Enable support for linking pcre2test with libreadline." ON)
466+
endif()
467+
468+
# Prepare build configuration
469+
470+
include_directories(${PROJECT_BINARY_DIR}/interface ${PROJECT_BINARY_DIR}/src ${PROJECT_SOURCE_DIR}/src)
471+
472+
if(NOT BUILD_SHARED_LIBS AND NOT BUILD_STATIC_LIBS)
473+
message(FATAL_ERROR "At least one of BUILD_SHARED_LIBS or BUILD_STATIC_LIBS must be enabled.")
474+
endif()
475+
476+
if(NOT PCRE2_BUILD_PCRE2_8 AND NOT PCRE2_BUILD_PCRE2_16 AND NOT PCRE2_BUILD_PCRE2_32)
477+
message(
478+
FATAL_ERROR
479+
"At least one of PCRE2_BUILD_PCRE2_8, PCRE2_BUILD_PCRE2_16 or PCRE2_BUILD_PCRE2_32 must be enabled"
480+
)
481+
endif()
482+
483+
if(PCRE2_BUILD_PCRE2_8)
484+
set(SUPPORT_PCRE2_8 1)
485+
endif()
486+
487+
if(PCRE2_BUILD_PCRE2_16)
488+
set(SUPPORT_PCRE2_16 1)
489+
endif()
490+
491+
if(PCRE2_BUILD_PCRE2_32)
492+
set(SUPPORT_PCRE2_32 1)
493+
endif()
494+
495+
if(PCRE2_BUILD_PCRE2GREP AND NOT PCRE2_BUILD_PCRE2_8)
496+
message(STATUS "** PCRE2_BUILD_PCRE2_8 must be enabled for the pcre2grep program")
497+
set(PCRE2_BUILD_PCRE2GREP OFF)
498+
endif()
499+
475500
if(PCRE2_SUPPORT_LIBBZ2)
476501
if(BZIP2_FOUND)
477502
include_directories(${BZIP2_INCLUDE_DIR})
@@ -484,10 +509,6 @@ if(PCRE2_SUPPORT_LIBBZ2)
484509
endif()
485510
endif()
486511

487-
# zlib
488-
if(ZLIB_FOUND)
489-
option(PCRE2_SUPPORT_LIBZ "Enable support for linking pcre2grep with libz." ON)
490-
endif()
491512
if(PCRE2_SUPPORT_LIBZ)
492513
if(ZLIB_FOUND)
493514
include_directories(${ZLIB_INCLUDE_DIR})
@@ -500,10 +521,6 @@ if(PCRE2_SUPPORT_LIBZ)
500521
endif()
501522
endif()
502523

503-
# editline lib
504-
if(EDITLINE_FOUND)
505-
option(PCRE2_SUPPORT_LIBEDIT "Enable support for linking pcre2test with libedit." OFF)
506-
endif()
507524
if(PCRE2_SUPPORT_LIBEDIT)
508525
if(EDITLINE_FOUND)
509526
include_directories(${EDITLINE_INCLUDE_DIR})
@@ -516,10 +533,6 @@ if(PCRE2_SUPPORT_LIBEDIT)
516533
endif()
517534
endif()
518535

519-
# readline lib
520-
if(READLINE_FOUND)
521-
option(PCRE2_SUPPORT_LIBREADLINE "Enable support for linking pcre2test with libreadline." ON)
522-
endif()
523536
if(PCRE2_SUPPORT_LIBREADLINE)
524537
if(READLINE_FOUND)
525538
include_directories(${READLINE_INCLUDE_DIR})
@@ -532,36 +545,6 @@ if(PCRE2_SUPPORT_LIBREADLINE)
532545
endif()
533546
endif()
534547

535-
# Prepare build configuration
536-
537-
if(NOT BUILD_SHARED_LIBS AND NOT BUILD_STATIC_LIBS)
538-
message(FATAL_ERROR "At least one of BUILD_SHARED_LIBS or BUILD_STATIC_LIBS must be enabled.")
539-
endif()
540-
541-
if(NOT PCRE2_BUILD_PCRE2_8 AND NOT PCRE2_BUILD_PCRE2_16 AND NOT PCRE2_BUILD_PCRE2_32)
542-
message(
543-
FATAL_ERROR
544-
"At least one of PCRE2_BUILD_PCRE2_8, PCRE2_BUILD_PCRE2_16 or PCRE2_BUILD_PCRE2_32 must be enabled"
545-
)
546-
endif()
547-
548-
if(PCRE2_BUILD_PCRE2_8)
549-
set(SUPPORT_PCRE2_8 1)
550-
endif()
551-
552-
if(PCRE2_BUILD_PCRE2_16)
553-
set(SUPPORT_PCRE2_16 1)
554-
endif()
555-
556-
if(PCRE2_BUILD_PCRE2_32)
557-
set(SUPPORT_PCRE2_32 1)
558-
endif()
559-
560-
if(PCRE2_BUILD_PCRE2GREP AND NOT PCRE2_BUILD_PCRE2_8)
561-
message(STATUS "** PCRE2_BUILD_PCRE2_8 must be enabled for the pcre2grep program")
562-
set(PCRE2_BUILD_PCRE2GREP OFF)
563-
endif()
564-
565548
if(PCRE2_SUPPORT_LIBREADLINE AND PCRE2_SUPPORT_LIBEDIT)
566549
if(READLINE_FOUND)
567550
message(

Makefile.am

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1014,7 +1014,7 @@ EXTRA_DIST += \
10141014
cmake/FindEditline.cmake \
10151015
cmake/FindReadline.cmake \
10161016
cmake/pcre2-config.cmake.in \
1017-
cmake/PCRE2CheckLinkerFlag.cmake \
1017+
cmake/PCRE2CheckVscript.cmake \
10181018
cmake/PCRE2UseSystemExtensions.cmake \
10191019
cmake/PCRE2WarningAsError.cmake \
10201020
src/config-cmake.h.in \

NON-AUTOTOOLS-BUILD

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -429,8 +429,14 @@ applications can be supported through UNIX System Services.
429429
The PCRE2 codebase compiles and runs with native EBCDIC support on modern z/OS
430430
systems, using the pre-installed tools (/bin/sh, ./configure, and the XLC or
431431
IBM-Clang compilers). PCRE2 supports z/OS using both Autoconf (./configure) and
432-
CMake (which IBM distributes via "zopen install cmake"). Any EBCDIC codepage
433-
should work (PCRE2 does not assume or require IBM-1047).
432+
CMake (which IBM distributes via "zopen install cmake").
433+
434+
Note that as of the time of writing, IBM's port of CMake to z/OS has only
435+
partial support for EBCDIC. It is recommended to build PCRE2 using the
436+
./configure script, if you require an EBCDIC build.
437+
438+
Any EBCDIC codepage should work (PCRE2 does not assume or require IBM-1047), or
439+
PCRE2 can compiled for ASCII/Latin-1/Unicode.
434440

435441
After unpacking the PCRE2 tarball, you must subsequently tag the files as ASCII
436442
in order for the z/OS shell and compiler to interpret them correctly:

README

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -974,7 +974,7 @@ The distribution should contain the files listed below.
974974
cmake/FindEditline.cmake
975975
cmake/FindReadline.cmake
976976
cmake/pcre2-config.cmake.in
977-
cmake/PCRE2CheckLinkerFlag.cmake
977+
cmake/PCRE2CheckVscript.cmake
978978
cmake/PCRE2UseSystemExtensions.cmake
979979
cmake/PCRE2WarningAsError.cmake
980980
src/config-cmake.h.in

cmake/PCRE2CheckLinkerFlag.cmake

Lines changed: 0 additions & 26 deletions
This file was deleted.

cmake/PCRE2CheckVscript.cmake

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
# Similarly to Autoconf's ax_check_vscript.m4, check whether the linker supports
2+
# version scripts (GNU ld) or map files (Sun linker).
3+
# Sets the "have_var" to TRUE or FALSE depending on the detected support; and if
4+
# support is detected then sets "flag_var" to the appropriate flag to pass to
5+
# the linker (namely, --version-script or -M).
6+
7+
function(pcre2_check_vscript have_var flag_var)
8+
set(${have_var} FALSE PARENT_SCOPE)
9+
set(${flag_var} "" PARENT_SCOPE)
10+
11+
if(MSVC)
12+
return()
13+
endif()
14+
15+
set(first_run FALSE)
16+
if(NOT DEFINED HAVE_VSCRIPT_GNU)
17+
set(first_run TRUE)
18+
message(STATUS "Detecting linker version script support")
19+
endif()
20+
21+
include(CheckCSourceCompiles)
22+
include(CMakePushCheckState)
23+
24+
# The BSD file here is a workaround for the fact that check_c_source_compiles
25+
# very unfortunately only supports linking executables
26+
# with an entrypoint (or a static library), and yet the symbol visibility
27+
# requirements for executables are understandably different on some platforms
28+
# as compared to linking a shared library. On FreeBSD, linking fails if you
29+
# use the linker script to hide various global symbols from /usr/lib/crt1.o.
30+
# https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=269370
31+
# Basically, everyone using --version-script is actually going to be creating
32+
# a shared library. It's a frustrating mismatch.
33+
file(WRITE ${PROJECT_BINARY_DIR}/test-map-file.sym "PCRE2_10.00 { global: exposethis; local: *; };")
34+
file(WRITE ${PROJECT_BINARY_DIR}/test-map-file-bsd.sym "PCRE2_10.00 { global: exposethis; environ; __progname; local: *; };")
35+
file(WRITE ${PROJECT_BINARY_DIR}/test-map-file-broken.sym "PCRE2_10.00 { global: exposethis; local: *; }; {")
36+
37+
set(HAVE_VSCRIPT FALSE)
38+
39+
# Using an executable to check for version-script support is rather delicate,
40+
# because linking in an entrypoint (main) adds extra symbols into the mix.
41+
# If CMake ever added a SHARED_LIBRARY option to check_c_source_compiles, we'd
42+
# use it here.
43+
set(
44+
test_source
45+
[=[
46+
int exposethis = 0, hidethis = 0;
47+
int main(void) {
48+
return exposethis + hidethis;
49+
}
50+
]=]
51+
)
52+
53+
cmake_push_check_state(RESET)
54+
set(CMAKE_REQUIRED_QUIET TRUE)
55+
56+
set(CMAKE_REQUIRED_LINK_OPTIONS "-Wl,--version-script,${PROJECT_BINARY_DIR}/test-map-file.sym")
57+
check_c_source_compiles("${test_source}" HAVE_VSCRIPT_GNU)
58+
59+
if(HAVE_VSCRIPT_GNU)
60+
set(VSCRIPT_FLAG --version-script)
61+
set(HAVE_VSCRIPT TRUE)
62+
else()
63+
set(CMAKE_REQUIRED_LINK_OPTIONS "-Wl,--version-script,${PROJECT_BINARY_DIR}/test-map-file-bsd.sym")
64+
check_c_source_compiles("${test_source}" HAVE_VSCRIPT_BSD)
65+
66+
if(HAVE_VSCRIPT_BSD)
67+
set(VSCRIPT_FLAG --version-script)
68+
set(HAVE_VSCRIPT TRUE)
69+
else()
70+
set(CMAKE_REQUIRED_LINK_OPTIONS "-Wl,-M,${PROJECT_BINARY_DIR}/test-map-file.sym")
71+
check_c_source_compiles("${test_source}" HAVE_VSCRIPT_SUN)
72+
73+
if(HAVE_VSCRIPT_SUN)
74+
set(VSCRIPT_FLAG -M)
75+
set(HAVE_VSCRIPT TRUE)
76+
endif()
77+
endif()
78+
endif()
79+
80+
if(HAVE_VSCRIPT)
81+
# Perform the same logic as ax_check_vscript.m4, to test whether the linker
82+
# silently ignores (and overwrites) linker scripts it doesn't understand.
83+
set(CMAKE_REQUIRED_LINK_OPTIONS "-Wl,${VSCRIPT_FLAG},${PROJECT_BINARY_DIR}/test-map-file-broken.sym")
84+
check_c_source_compiles("${test_source}" HAVE_VSCRIPT_BROKEN)
85+
86+
if(HAVE_VSCRIPT_BROKEN)
87+
set(HAVE_VSCRIPT FALSE)
88+
if(first_run)
89+
message(STATUS "Detecting linker version script support - no (linker overwrites unknown scripts)")
90+
endif()
91+
else()
92+
if(first_run)
93+
message(STATUS "Detecting linker version script support - yes (${VSCRIPT_FLAG})")
94+
endif()
95+
endif()
96+
else()
97+
if(first_run)
98+
message(STATUS "Detecting linker version script support - none detected")
99+
endif()
100+
endif()
101+
102+
cmake_pop_check_state()
103+
104+
file(REMOVE ${PROJECT_BINARY_DIR}/test-map-file.sym)
105+
file(REMOVE ${PROJECT_BINARY_DIR}/test-map-file-bsd.sym)
106+
file(REMOVE ${PROJECT_BINARY_DIR}/test-map-file-broken.sym)
107+
108+
if(HAVE_VSCRIPT)
109+
set(${have_var} TRUE PARENT_SCOPE)
110+
set(${flag_var} "${VSCRIPT_FLAG}" PARENT_SCOPE)
111+
endif()
112+
endfunction()

0 commit comments

Comments
 (0)