Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ config.guess
config.log
config.status
config.sub
config.lt
configure
depcomp
install-sh
Expand Down Expand Up @@ -106,6 +107,10 @@ src/config.h
src/config.h.in
src/pcre2.h
src/pcre2_chartables.c
src/libpcre2-8.sym
src/libpcre2-16.sym
src/libpcre2-32.sym
src/libpcre2-posix.sym
src/stamp-h1

/bazel-*
Expand Down
48 changes: 31 additions & 17 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ check_c_source_compiles(

# Detect support for linker scripts.

pcre2_check_vscript(HAVE_VSCRIPT VSCRIPT_FLAG)
pcre2_check_vscript(HAVE_VSCRIPT VSCRIPT_FLAG HAVE_VSCRIPT_NO_STAR)

# Check whether Intel CET is enabled, and if so, adjust compiler flags. This
# code was written by PH, trying to imitate the logic from the autotools
Expand Down Expand Up @@ -702,10 +702,6 @@ endif()
file(REMOVE ${PROJECT_SOURCE_DIR}/src/config.h)
file(REMOVE ${PROJECT_SOURCE_DIR}/src/pcre2.h)

# Output files

configure_file(src/config-cmake.h.in ${PROJECT_BINARY_DIR}/src/config.h @ONLY)

# Parse version numbers and date out of configure.ac

file(
Expand Down Expand Up @@ -762,13 +758,26 @@ parse_lib_version(LIBPCRE2_8)
parse_lib_version(LIBPCRE2_16)
parse_lib_version(LIBPCRE2_32)

# Output files

configure_file(src/config-cmake.h.in ${PROJECT_BINARY_DIR}/src/config.h @ONLY)

configure_file(src/pcre2.h.in ${PROJECT_BINARY_DIR}/interface/pcre2.h @ONLY)
configure_file(src/pcre2posix.h ${PROJECT_BINARY_DIR}/interface/pcre2posix.h COPYONLY)

# Make sure to not link debug libs
# against release libs and vice versa
if(WIN32)
set(CMAKE_DEBUG_POSTFIX "d")
# Configure the version script files.

if(HAVE_VSCRIPT AND PCRE2_SYMVERS)
if(HAVE_VSCRIPT_NO_STAR)
set(PCRE2_EXTRA_LOCAL_SYMS "")
else()
set(PCRE2_EXTRA_LOCAL_SYMS " local: *;")
endif()

configure_file(src/libpcre2-8.sym.in ${PROJECT_BINARY_DIR}/src/libpcre2-8.sym @ONLY)
configure_file(src/libpcre2-16.sym.in ${PROJECT_BINARY_DIR}/src/libpcre2-16.sym @ONLY)
configure_file(src/libpcre2-32.sym.in ${PROJECT_BINARY_DIR}/src/libpcre2-32.sym @ONLY)
configure_file(src/libpcre2-posix.sym.in ${PROJECT_BINARY_DIR}/src/libpcre2-posix.sym @ONLY)
endif()

# Character table generation
Expand Down Expand Up @@ -893,6 +902,11 @@ if(MSVC)
add_compile_definitions(_CRT_SECURE_NO_DEPRECATE _CRT_SECURE_NO_WARNINGS)
endif()

# Make sure to not link debug libs against release libs and vice versa.
if(WIN32)
set(CMAKE_DEBUG_POSTFIX "d")
endif()

set(TARGETS)
set(DLL_PDB_FILES)
set(DLL_PDB_DEBUG_FILES)
Expand Down Expand Up @@ -969,8 +983,8 @@ if(PCRE2_BUILD_PCRE2_8)
target_link_libraries(pcre2-8-shared Threads::Threads)
endif()
if(HAVE_VSCRIPT AND PCRE2_SYMVERS)
target_link_options(pcre2-8-shared PRIVATE -Wl,${VSCRIPT_FLAG},${PROJECT_SOURCE_DIR}/src/libpcre2-8.sym)
set_target_properties(pcre2-8-shared PROPERTIES LINK_DEPENDS ${PROJECT_SOURCE_DIR}/src/libpcre2-8.sym)
target_link_options(pcre2-8-shared PRIVATE -Wl,${VSCRIPT_FLAG},${PROJECT_BINARY_DIR}/src/libpcre2-8.sym)
set_target_properties(pcre2-8-shared PROPERTIES LINK_DEPENDS ${PROJECT_BINARY_DIR}/src/libpcre2-8.sym)
endif()
list(APPEND TARGETS pcre2-8-shared)
list(APPEND DLL_PDB_FILES $<TARGET_PDB_FILE_DIR:pcre2-8-shared>/pcre2-8.pdb)
Expand All @@ -992,8 +1006,8 @@ if(PCRE2_BUILD_PCRE2_8)
OUTPUT_NAME pcre2-posix
)
if(HAVE_VSCRIPT AND PCRE2_SYMVERS)
target_link_options(pcre2-posix-shared PRIVATE -Wl,${VSCRIPT_FLAG},${PROJECT_SOURCE_DIR}/src/libpcre2-posix.sym)
set_target_properties(pcre2-posix-shared PROPERTIES LINK_DEPENDS ${PROJECT_SOURCE_DIR}/src/libpcre2-posix.sym)
target_link_options(pcre2-posix-shared PRIVATE -Wl,${VSCRIPT_FLAG},${PROJECT_BINARY_DIR}/src/libpcre2-posix.sym)
set_target_properties(pcre2-posix-shared PROPERTIES LINK_DEPENDS ${PROJECT_BINARY_DIR}/src/libpcre2-posix.sym)
endif()
target_compile_definitions(pcre2-posix-shared PUBLIC PCRE2POSIX_SHARED)
target_link_libraries(pcre2-posix-shared pcre2-8-shared)
Expand Down Expand Up @@ -1074,8 +1088,8 @@ if(PCRE2_BUILD_PCRE2_16)
target_link_libraries(pcre2-16-shared Threads::Threads)
endif()
if(HAVE_VSCRIPT AND PCRE2_SYMVERS)
target_link_options(pcre2-16-shared PRIVATE -Wl,${VSCRIPT_FLAG},${PROJECT_SOURCE_DIR}/src/libpcre2-16.sym)
set_target_properties(pcre2-16-shared PROPERTIES LINK_DEPENDS ${PROJECT_SOURCE_DIR}/src/libpcre2-16.sym)
target_link_options(pcre2-16-shared PRIVATE -Wl,${VSCRIPT_FLAG},${PROJECT_BINARY_DIR}/src/libpcre2-16.sym)
set_target_properties(pcre2-16-shared PROPERTIES LINK_DEPENDS ${PROJECT_BINARY_DIR}/src/libpcre2-16.sym)
endif()
list(APPEND TARGETS pcre2-16-shared)
list(APPEND DLL_PDB_FILES $<TARGET_PDB_FILE_DIR:pcre2-16-shared>/pcre2-16.pdb)
Expand Down Expand Up @@ -1152,8 +1166,8 @@ if(PCRE2_BUILD_PCRE2_32)
target_link_libraries(pcre2-32-shared Threads::Threads)
endif()
if(HAVE_VSCRIPT AND PCRE2_SYMVERS)
target_link_options(pcre2-32-shared PRIVATE -Wl,${VSCRIPT_FLAG},${PROJECT_SOURCE_DIR}/src/libpcre2-32.sym)
set_target_properties(pcre2-32-shared PROPERTIES LINK_DEPENDS ${PROJECT_SOURCE_DIR}/src/libpcre2-32.sym)
target_link_options(pcre2-32-shared PRIVATE -Wl,${VSCRIPT_FLAG},${PROJECT_BINARY_DIR}/src/libpcre2-32.sym)
set_target_properties(pcre2-32-shared PROPERTIES LINK_DEPENDS ${PROJECT_BINARY_DIR}/src/libpcre2-32.sym)
endif()
list(APPEND TARGETS pcre2-32-shared)
list(APPEND DLL_PDB_FILES $<TARGET_PDB_FILE_DIR:pcre2-32-shared>/pcre2-32.pdb)
Expand Down
8 changes: 4 additions & 4 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -278,8 +278,8 @@ EXTRA_DIST =
# These files contain additional m4 macros that are used by autoconf.

EXTRA_DIST += \
m4/ax_check_vscript.m4 \
m4/ax_pthread.m4 \
m4/pcre2_check_vscript.m4 \
m4/pcre2_visibility.m4 \
m4/pcre2_zos.m4

Expand Down Expand Up @@ -897,11 +897,11 @@ pkgconfig_DATA += libpcre2-32.pc
endif


# Symbol version files for use with GNU and Sun ld.
# Symbol version template files for use with GNU and Sun ld.

EXTRA_DIST += \
src/libpcre2-8.sym src/libpcre2-16.sym src/libpcre2-32.sym \
src/libpcre2-posix.sym
src/libpcre2-8.sym.in src/libpcre2-16.sym.in src/libpcre2-32.sym.in \
src/libpcre2-posix.sym.in


# gcov/lcov code coverage reporting
Expand Down
8 changes: 4 additions & 4 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -962,10 +962,10 @@ The distribution should contain the files listed below.
testdata/testoutput* expected test results
testdata/grep* input and output for pcre2grep tests
testdata/* other supporting test files
src/libpcre2-8.sym )
src/libpcre2-16.sym ) symbol version scripts for the GNU and Sun linkers
src/libpcre2-32.sym )
src/libpcre2-posix.sym )
src/libpcre2-8.sym.in )
src/libpcre2-16.sym.in ) symbol version script templates for the
src/libpcre2-32.sym.in ) GNU, BSD and Sun linkers
src/libpcre2-posix.sym.in )

(D) Auxiliary files for CMake support

Expand Down
153 changes: 91 additions & 62 deletions cmake/PCRE2CheckVscript.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,63 @@
# support is detected then sets "flag_var" to the appropriate flag to pass to
# the linker (namely, --version-script or -M).

function(pcre2_check_vscript have_var flag_var)
# Helper function: try to compile a shared library with a given linker flag and
# version script. This properly tests version script support by building a
# shared library rather than an executable, avoiding issues with
# executable-specific symbols (e.g. FreeBSD's crt1.o symbols, Solaris linker
# symbols in values-Xc.o).
function(_pcre2_try_vscript_shared_lib link_flag map_file result_var)
if(DEFINED ${result_var})
return()
endif()

message(STATUS "Performing Test ${result_var}")

set(${result_var} FALSE PARENT_SCOPE)

set(try_dir "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CMakeScratch/CheckVscript")
file(REMOVE_RECURSE "${try_dir}")
file(MAKE_DIRECTORY "${try_dir}")

# Write a minimal C source with exported symbols
file(WRITE "${try_dir}/test_vscript.c" "
int hidethis(void) { return 0; }
int exposethis(void) { return hidethis(); }
")

# Write a CMakeLists.txt that builds a shared library with the version script
file(WRITE "${try_dir}/CMakeLists.txt" "
cmake_minimum_required(VERSION 3.15)
project(test_vscript C)
add_library(test_vscript SHARED test_vscript.c)
target_link_options(test_vscript PRIVATE \"-Wl,${link_flag},${map_file}\")
")

try_compile(
compile_result
"${try_dir}/build" # BINARY_DIR
"${try_dir}" # SOURCE_DIR
test_vscript # Project name
OUTPUT_VARIABLE compile_output
)

if(compile_result)
set(${result_var} TRUE PARENT_SCOPE)
endif()

if(${compile_result})
set(${result_var} 1 CACHE INTERNAL "Test ${result_var}")
message(STATUS "Performing Test ${result_var} - Success")
else()
set(${result_var} "" CACHE INTERNAL "Test ${result_var}")
message(STATUS "Performing Test ${result_var} - Failed")
endif()
endfunction()

function(pcre2_check_vscript have_var flag_var no_star_var)
set(${have_var} FALSE PARENT_SCOPE)
set(${flag_var} "" PARENT_SCOPE)
set(${no_star_var} FALSE PARENT_SCOPE)

if(MSVC)
return()
Expand All @@ -18,95 +72,70 @@ function(pcre2_check_vscript have_var flag_var)
message(STATUS "Detecting linker version script support")
endif()

include(CheckCSourceCompiles)
include(CMakePushCheckState)

# The BSD file here is a workaround for the fact that check_c_source_compiles
# very unfortunately only supports linking executables
# with an entrypoint (or a static library), and yet the symbol visibility
# requirements for executables are understandably different on some platforms
# as compared to linking a shared library. On FreeBSD, linking fails if you
# use the linker script to hide various global symbols from /usr/lib/crt1.o.
# https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=269370
# Basically, everyone using --version-script is actually going to be creating
# a shared library. It's a frustrating mismatch.
file(WRITE ${PROJECT_BINARY_DIR}/test-map-file.sym "PCRE2_10.00 { global: exposethis; local: *; };")
file(WRITE ${PROJECT_BINARY_DIR}/test-map-file-bsd.sym "PCRE2_10.00 { global: exposethis; environ; __progname; local: *; };")
file(WRITE ${PROJECT_BINARY_DIR}/test-map-file-broken.sym "PCRE2_10.00 { global: exposethis; local: *; }; {")
# Write test version script files
file(WRITE "${PROJECT_BINARY_DIR}/test-map-file.sym" "PCRE2_10.00 { global: exposethis; local: *; };")
file(WRITE "${PROJECT_BINARY_DIR}/test-map-file-broken.sym" "PCRE2_10.00 { global: exposethis; local: *; }; {")
file(WRITE "${PROJECT_BINARY_DIR}/test-map-file-no-star.sym" "PCRE2_10.00 { global: exposethis; local: hidethis; };")

set(HAVE_VSCRIPT FALSE)

# Using an executable to check for version-script support is rather delicate,
# because linking in an entrypoint (main) adds extra symbols into the mix.
# If CMake ever added a SHARED_LIBRARY option to check_c_source_compiles, we'd
# use it here.
set(
test_source
[=[
int exposethis = 0, hidethis = 0;
int main(void) {
return exposethis + hidethis;
}
]=]
)

cmake_push_check_state(RESET)
set(CMAKE_REQUIRED_QUIET TRUE)

set(CMAKE_REQUIRED_LINK_OPTIONS "-Wl,--version-script,${PROJECT_BINARY_DIR}/test-map-file.sym")
check_c_source_compiles("${test_source}" HAVE_VSCRIPT_GNU)
# Test GNU ld --version-script flag
_pcre2_try_vscript_shared_lib("--version-script" "${PROJECT_BINARY_DIR}/test-map-file.sym" HAVE_VSCRIPT_GNU)

if(HAVE_VSCRIPT_GNU)
set(VSCRIPT_FLAG --version-script)
set(HAVE_VSCRIPT TRUE)
else()
set(CMAKE_REQUIRED_LINK_OPTIONS "-Wl,--version-script,${PROJECT_BINARY_DIR}/test-map-file-bsd.sym")
check_c_source_compiles("${test_source}" HAVE_VSCRIPT_BSD)
# Test Sun linker -M flag
_pcre2_try_vscript_shared_lib("-M" "${PROJECT_BINARY_DIR}/test-map-file.sym" HAVE_VSCRIPT_SUN)

if(HAVE_VSCRIPT_BSD)
set(VSCRIPT_FLAG --version-script)
if(HAVE_VSCRIPT_SUN)
set(VSCRIPT_FLAG -M)
set(HAVE_VSCRIPT TRUE)
else()
set(CMAKE_REQUIRED_LINK_OPTIONS "-Wl,-M,${PROJECT_BINARY_DIR}/test-map-file.sym")
check_c_source_compiles("${test_source}" HAVE_VSCRIPT_SUN)

if(HAVE_VSCRIPT_SUN)
set(VSCRIPT_FLAG -M)
set(HAVE_VSCRIPT TRUE)
endif()
endif()
endif()

if(HAVE_VSCRIPT)
# Perform the same logic as ax_check_vscript.m4, to test whether the linker
# silently ignores (and overwrites) linker scripts it doesn't understand.
set(CMAKE_REQUIRED_LINK_OPTIONS "-Wl,${VSCRIPT_FLAG},${PROJECT_BINARY_DIR}/test-map-file-broken.sym")
check_c_source_compiles("${test_source}" HAVE_VSCRIPT_BROKEN)
_pcre2_try_vscript_shared_lib("${VSCRIPT_FLAG}" "${PROJECT_BINARY_DIR}/test-map-file-broken.sym" HAVE_VSCRIPT_BROKEN)

if(HAVE_VSCRIPT_BROKEN)
set(HAVE_VSCRIPT FALSE)
if(first_run)
message(STATUS "Detecting linker version script support - no (linker overwrites unknown scripts)")
endif()
else()
if(first_run)
message(STATUS "Detecting linker version script support - yes (${VSCRIPT_FLAG})")
endif()
endif()
else()
if(first_run)
endif()

if(first_run)
if(HAVE_VSCRIPT)
message(STATUS "Detecting linker version script support - yes (${VSCRIPT_FLAG})")
elseif(HAVE_VSCRIPT_BROKEN)
message(STATUS "Detecting linker version script support - no (linker overwrites unknown scripts)")
else()
message(STATUS "Detecting linker version script support - none detected")
endif()
endif()

cmake_pop_check_state()
if(HAVE_VSCRIPT)
if(first_run)
message(STATUS "Detecting if version scripts work without wildcard")
endif()

# Test that the linker works without requiring a wildcard to hide platform-specific
# symbols (_init, _fini, etc.).
_pcre2_try_vscript_shared_lib("${VSCRIPT_FLAG}" "${PROJECT_BINARY_DIR}/test-map-file-no-star.sym" HAVE_VSCRIPT_NO_STAR)

if(first_run)
message(STATUS "Detecting if version scripts work without wildcard - ${HAVE_VSCRIPT_NO_STAR}")
endif()
endif()

file(REMOVE ${PROJECT_BINARY_DIR}/test-map-file.sym)
file(REMOVE ${PROJECT_BINARY_DIR}/test-map-file-bsd.sym)
file(REMOVE ${PROJECT_BINARY_DIR}/test-map-file-broken.sym)
file(REMOVE "${PROJECT_BINARY_DIR}/test-map-file.sym")
file(REMOVE "${PROJECT_BINARY_DIR}/test-map-file-broken.sym")
file(REMOVE "${PROJECT_BINARY_DIR}/test-map-file-no-star.sym")

if(HAVE_VSCRIPT)
set(${have_var} TRUE PARENT_SCOPE)
set(${flag_var} "${VSCRIPT_FLAG}" PARENT_SCOPE)
set(${no_star_var} "${HAVE_VSCRIPT_NO_STAR}" PARENT_SCOPE)
endif()
endfunction()
Loading
Loading