Skip to content

Commit 278e0be

Browse files
committed
Rewrite FindPCRE.cmake
Complete rewrite of FindPCRE.cmake module from scratch; - Properly allocate both release and debug libraries - Automatically prefer static libraries if found - Properly check the set required version and use find_package_handle_standard_Args to throw an error if the version isn't matching or higher than requested
1 parent 89074e2 commit 278e0be

File tree

2 files changed

+96
-36
lines changed

2 files changed

+96
-36
lines changed

CMakeLists.txt

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -123,12 +123,6 @@ include_directories(${ZLIB_INCLUDE_DIR})
123123
# PCRE #
124124
##############################
125125
find_package(PCRE 8.39 REQUIRED)
126-
include_directories(${PCRE_INCLUDE_DIR})
127-
option(PCRE_STATIC_LIB "Statically link to PCRE" ON)
128-
129-
if(PCRE_STATIC_LIB)
130-
add_definitions(-DPCRE_STATIC)
131-
endif()
132126

133127
##############################
134128
# Google Test #

cmake/FindPCRE.cmake

Lines changed: 96 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,104 @@
1-
# Copyright (C) 2007-2009 LuaDist.
2-
# Created by Peter Kapec <kapecp@gmail.com>
3-
# Redistribution and use of this file is allowed according to the terms of the MIT license.
4-
# For details see the COPYRIGHT file distributed with LuaDist.
5-
# Note:
6-
# Searching headers and libraries is very simple and is NOT as powerful as scripts
7-
# distributed with CMake, because LuaDist defines directories to search for.
8-
# Everyone is encouraged to contact the author with improvements. Maybe this file
9-
# becomes part of CMake distribution sometimes.
10-
11-
# - Find pcre
12-
# Find the native PCRE headers and libraries.
1+
# Copyright (c) 2025 Ember
132
#
14-
# PCRE_INCLUDE_DIRS - where to find pcre.h, etc.
15-
# PCRE_LIBRARIES - List of libraries when using pcre.
16-
# PCRE_FOUND - True if pcre found.
3+
# This Source Code Form is subject to the terms of the Mozilla Public
4+
# License, v. 2.0. If a copy of the MPL was not distributed with this
5+
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
6+
7+
SET(PCRE_POSSIBLE_LIBRARY_NAMES pcre libpcre)
8+
SET(PCRE_POSSIBLE_LIB_SUFFIX lib)
9+
SET(PCRE_POSSIBLE_LIBD_SUFFIX debug/lib)
10+
SET(POSSIBLE_STATICLIB_NAMES pcre.a libpcre.a pcre-static.lib)
1711

1812
# Look for the header file.
19-
FIND_PATH(PCRE_INCLUDE_DIR NAMES pcre.h)
13+
FIND_PATH(PCRE_INCLUDE_DIR
14+
NAMES pcre.h
15+
PATH_SUFFIXES include
16+
DOC "pcre include directory")
17+
18+
# Look for the release library.
19+
FIND_LIBRARY(PCRE_LIBRARY_RELEASE
20+
NAMES ${PCRE_POSSIBLE_LIBRARY_NAMES}
21+
PATH_SUFFIXES ${PCRE_POSSIBLE_LIB_SUFFIX}
22+
DOC "pcre release library")
23+
24+
# Look for the debug library.
25+
FIND_LIBRARY(PCRE_LIBRARY_DEBUG
26+
NAMES ${PCRE_POSSIBLE_LIBRARY_NAMES}
27+
PATH_SUFFIXES ${PCRE_POSSIBLE_LIBD_SUFFIX}
28+
DOC "pcre debug library")
29+
30+
# Default to shared libraries.
31+
IF(PCRE_LIBRARY_RELEASE)
32+
IF(PCRE_LIBRARY_DEBUG)
33+
SET(PCRE_LIBRARY
34+
optimized ${PCRE_LIBRARY_RELEASE}
35+
debug ${PCRE_LIBRARY_DEBUG}
36+
CACHE INTERNAL "PCRE library")
37+
ELSE()
38+
SET(PCRE_LIBRARY ${PCRE_LIBRARY_RELEASE} CACHE INTERNAL "PCRE library")
39+
ENDIF()
40+
41+
# Extract the directory from the found release library.
42+
GET_FILENAME_COMPONENT(PCRE_LIB_DIR "${PCRE_LIBRARY_RELEASE}" DIRECTORY)
43+
44+
# Check for static release candidate in that directory.
45+
FOREACH(candidate ${POSSIBLE_STATICLIB_NAMES})
46+
IF(EXISTS "${PCRE_LIB_DIR}/${candidate}")
47+
SET(PCRE_LIBRARY_STATIC_RELEASE "${PCRE_LIB_DIR}/${candidate}")
48+
BREAK()
49+
ENDIF()
50+
ENDFOREACH()
51+
52+
# If a debug build is sought, check for a static debug candidate.
53+
IF(PCRE_LIBRARY_DEBUG)
54+
FOREACH(candidate ${POSSIBLE_STATICLIB_NAMES})
55+
IF(EXISTS "${PCRE_LIB_DIR}/${candidate}")
56+
SET(PCRE_LIBRARY_STATIC_DEBUG "${PCRE_LIB_DIR}/${candidate}")
57+
BREAK()
58+
ENDIF()
59+
ENDFOREACH()
60+
ENDIF()
2061

21-
# Look for the library.
22-
FIND_LIBRARY(PCRE_LIBRARY NAMES pcre)
62+
# If we found a static release candidate, override the shared one.
63+
IF(PCRE_LIBRARY_STATIC_RELEASE)
64+
IF(PCRE_LIBRARY_DEBUG AND PCRE_LIBRARY_STATIC_DEBUG)
65+
SET(PCRE_LIBRARY
66+
optimized "${PCRE_LIBRARY_STATIC_RELEASE}"
67+
debug "${PCRE_LIBRARY_STATIC_DEBUG}"
68+
CACHE INTERNAL "PCRE library" FORCE)
69+
ELSE()
70+
SET(PCRE_LIBRARY "${PCRE_LIBRARY_STATIC_RELEASE}" CACHE INTERNAL "PCRE library" FORCE)
71+
ENDIF()
72+
ENDIF()
73+
ENDIF()
2374

24-
# Handle the QUIETLY and REQUIRED arguments and set PCRE_FOUND to TRUE if all listed variables are TRUE.
25-
INCLUDE(FindPackageHandleStandardArgs)
26-
FIND_PACKAGE_HANDLE_STANDARD_ARGS(PCRE DEFAULT_MSG PCRE_LIBRARY PCRE_INCLUDE_DIR)
75+
IF(PCRE_LIBRARY_STATIC_RELEASE)
76+
MESSAGE(STATUS "Using PCRE static release library")
77+
ELSE()
78+
MESSAGE(STATUS "Using PCRE shared release library")
79+
ENDIF()
2780

28-
# Copy the results to the output variables.
29-
IF(PCRE_FOUND)
30-
SET(PCRE_LIBRARIES ${PCRE_LIBRARY})
31-
SET(PCRE_INCLUDE_DIRS ${PCRE_INCLUDE_DIR})
32-
ELSE(PCRE_FOUND)
33-
SET(PCRE_LIBRARIES)
34-
SET(PCRE_INCLUDE_DIRS)
35-
ENDIF(PCRE_FOUND)
81+
IF(PCRE_LIBRARY_STATIC_DEBUG)
82+
MESSAGE(STATUS "Also using PCRE static debug library")
83+
ELSEIF(PCRE_LIBRARY_DEBUG)
84+
MESSAGE(STATUS "Also using PCRE shared debug library")
85+
ENDIF()
3686

37-
MARK_AS_ADVANCED(PCRE_INCLUDE_DIRS PCRE_LIBRARIES)
87+
# Extract the version from the header and compare it to the required version.
88+
IF(PCRE_INCLUDE_DIR)
89+
SET(_PCRE_VERSION_HEADER "${PCRE_INCLUDE_DIR}/pcre.h")
90+
IF(EXISTS "${_PCRE_VERSION_HEADER}")
91+
FILE(STRINGS "${_PCRE_VERSION_HEADER}" _PCRE_VERSION_TMP REGEX "#define PCRE_(MAJOR|MINOR)[ \t]+[0-9]+")
92+
STRING(REGEX REPLACE ".*#define PCRE_MAJOR[ \t]+([0-9]+).*" "\\1" _PCRE_FOUND_MAJOR "${_PCRE_VERSION_TMP}")
93+
STRING(REGEX REPLACE ".*#define PCRE_MINOR[ \t]+([0-9]+).*" "\\1" _PCRE_FOUND_MINOR "${_PCRE_VERSION_TMP}")
94+
SET(_PCRE_FOUND_VERSION "${_PCRE_FOUND_MAJOR}.${_PCRE_FOUND_MINOR}")
95+
IF(_PCRE_FOUND_VERSION VERSION_GREATER_EQUAL "${PCRE_VERSION}")
96+
SET(PCRE_VERSION "${_PCRE_FOUND_VERSION}")
97+
ELSE() # The found version is too old; clear PCRE_VERSION so that the handler later will throw an error.
98+
UNSET(PCRE_VERSION)
99+
ENDIF()
100+
ENDIF()
101+
ENDIF()
38102

103+
# Handle the QUIETLY and REQUIRED arguments and mark PCRE as found if all listed variables are TRUE.
104+
FIND_PACKAGE_HANDLE_STANDARD_ARGS(PCRE REQUIRED_VARS PCRE_INCLUDE_DIR PCRE_LIBRARY VERSION_VAR PCRE_VERSION)

0 commit comments

Comments
 (0)