Skip to content

Commit d6a8a69

Browse files
committed
windows: integrate visibility attributes without conflicts
When using a DLL in Windows, the function declarations (and definitions) that are public are decorated with attributes but those declarations would conflict with the ones that are selected when the compiler supports the visibility feature. Define instead a new macro that would be added to the corresponding macros independently and while at it allow setting visibility with cmake.
1 parent 1bc34ff commit d6a8a69

14 files changed

+96
-127
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,19 @@ missing
4040
pcre2-config
4141
pcre2_dftables
4242
pcre2_jit_test
43+
pcre2_jit_test.exe
4344
pcre2_jit_test.log
4445
pcre2_jit_test.trs
4546
pcre2posix_test
47+
pcre2posix_test.exe
4648
pcre2posix_test.log
4749
pcre2posix_test.trs
4850
pcre2demo
4951
pcre2fuzzcheck
5052
pcre2grep
53+
pcre2grep.exe
5154
pcre2test
55+
pcre2test.exe
5256
test-driver
5357
test-suite.log
5458
test3input

CMakeLists.txt

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -102,13 +102,15 @@
102102
# 2022-12-10 PH added support for pcre2posix_test
103103
# 2023-01-15 Carlo added C99 as the minimum required
104104

105-
# Increased minimum to 2.8.5 to support GNUInstallDirs.
106-
# Increased minimum to 3.1 to support imported targets.
107-
CMAKE_MINIMUM_REQUIRED(VERSION 3.1)
105+
# Increased minimum to 3.3 to support visibility.
106+
CMAKE_MINIMUM_REQUIRED(VERSION 3.3)
108107
PROJECT(PCRE2 C)
109108
set(CMAKE_C_STANDARD 99)
110109
set(CMAKE_C_STANDARD_REQUIRED TRUE)
111110

111+
set(CMAKE_C_VISIBILITY_PRESET hidden)
112+
cmake_policy(SET CMP0063 NEW)
113+
112114
# Set policy CMP0026 to avoid warnings for the use of LOCATION in
113115
# GET_TARGET_PROPERTY. This should no longer be required.
114116
# CMAKE_POLICY(SET CMP0026 OLD)
@@ -156,7 +158,7 @@ CHECK_SYMBOL_EXISTS(strerror "string.h" HAVE_STRERROR)
156158
CHECK_C_SOURCE_COMPILES(
157159
"#include <stdlib.h>
158160
#include <limits.h>
159-
int main(int c, char *v[]) { char buf[PATH_MAX]; realpath(v[1], buf); return 0; }"
161+
int main(int c, char *v[]) { char buf[PATH_MAX]; realpath(v[c], buf); return 0; }"
160162
HAVE_REALPATH
161163
)
162164

@@ -165,14 +167,28 @@ set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Werror")
165167

166168
CHECK_C_SOURCE_COMPILES(
167169
"#include <stddef.h>
168-
int main() { int a,b; size_t m; __builtin_mul_overflow(a,b,&m); return 0; }"
170+
int main(void) { int a,b; size_t m; __builtin_mul_overflow(a,b,&m); return 0; }"
169171
HAVE_BUILTIN_MUL_OVERFLOW
170172
)
171173

172174
CHECK_C_SOURCE_COMPILES(
173-
"int main() { char buf[128] __attribute__((uninitialized)); (void)buf; return 0; }"
175+
"int main(void) { char buf[128] __attribute__((uninitialized)); (void)buf; return 0; }"
174176
HAVE_ATTRIBUTE_UNINITIALIZED
175177
)
178+
179+
CHECK_C_SOURCE_COMPILES([=[
180+
extern __attribute__ ((visibility ("default"))) int f(void);
181+
int main(void) { return f(); }
182+
int f(void) { return 42; }
183+
]=] HAVE_VISIBILITY
184+
)
185+
186+
if (HAVE_VISIBILITY)
187+
set(PCRE2_EXPORT [=[__attribute__ ((visibility ("default")))]=])
188+
else()
189+
set(PCRE2_EXPORT)
190+
endif()
191+
176192
set(CMAKE_REQUIRED_FLAGS ${ORIG_CMAKE_REQUIRED_FLAGS})
177193

178194
# Check whether Intel CET is enabled, and if so, adjust compiler flags. This
@@ -191,8 +207,6 @@ IF (INTEL_CET_ENABLED)
191207
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mshstk")
192208
ENDIF(INTEL_CET_ENABLED)
193209

194-
195-
196210
# User-configurable options
197211
#
198212
# Note: CMakeSetup displays these in alphabetical order, regardless of
@@ -729,7 +743,6 @@ IF(PCRE2_BUILD_PCRE2_8)
729743
VERSION ${LIBPCRE2_POSIX_VERSION}
730744
SOVERSION ${LIBPCRE2_POSIX_SOVERSION})
731745
TARGET_LINK_LIBRARIES(pcre2-posix-static pcre2-8-static)
732-
TARGET_COMPILE_DEFINITIONS(pcre2-posix-static PUBLIC PCRE2_STATIC)
733746
TARGET_INCLUDE_DIRECTORIES(pcre2-posix-static PUBLIC ${PROJECT_BINARY_DIR})
734747
SET(targets ${targets} pcre2-posix-static)
735748

@@ -759,6 +772,7 @@ IF(PCRE2_BUILD_PCRE2_8)
759772
TARGET_LINK_LIBRARIES(pcre2-8-shared Threads::Threads)
760773
ENDIF(REQUIRE_PTHREAD)
761774
SET(targets ${targets} pcre2-8-shared)
775+
762776
ADD_LIBRARY(pcre2-posix-shared SHARED ${PCRE2POSIX_HEADERS} ${PCRE2POSIX_SOURCES})
763777
TARGET_INCLUDE_DIRECTORIES(pcre2-posix-shared PUBLIC ${PROJECT_BINARY_DIR})
764778
SET_TARGET_PROPERTIES(pcre2-posix-shared PROPERTIES
@@ -768,6 +782,7 @@ IF(PCRE2_BUILD_PCRE2_8)
768782
VERSION ${LIBPCRE2_POSIX_VERSION}
769783
SOVERSION ${LIBPCRE2_POSIX_SOVERSION}
770784
OUTPUT_NAME pcre2-posix)
785+
TARGET_COMPILE_DEFINITIONS(pcre2-posix-shared PUBLIC PCRE2POSIX_SHARED)
771786
TARGET_LINK_LIBRARIES(pcre2-posix-shared pcre2-8-shared)
772787
SET(targets ${targets} pcre2-posix-shared)
773788
SET(dll_pdb_files ${PROJECT_BINARY_DIR}/pcre2-8.pdb ${dll_pdb_files})

Makefile.am

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -292,8 +292,7 @@ src/pcre2.h.generic: src/pcre2.h.in configure.ac
292292
# config.status out of the way while doing the default configuration. The
293293
# resulting config.h is munged by perl to put #ifdefs round any #defines for
294294
# macros with values, and to #undef all boolean macros such as HAVE_xxx and
295-
# SUPPORT_xxx. We also get rid of any gcc-specific visibility settings. Make
296-
# sure that PCRE2_EXP_DEFN is unset (in case it has visibility settings).
295+
# SUPPORT_xxx. We also get rid of any gcc-specific visibility settings.
297296

298297
src/config.h.generic: configure.ac
299298
rm -rf $@ _generic
@@ -304,9 +303,7 @@ src/config.h.generic: configure.ac
304303
test -f _generic/src/config.h
305304
perl -n \
306305
-e 'BEGIN{$$blank=0;}' \
307-
-e 'if(/PCRE2_EXP_DEFN/){print"/* #undef PCRE2_EXP_DEFN */\n";$$blank=0;next;}' \
308-
-e 'if(/to make a symbol visible/){next;}' \
309-
-e 'if(/__attribute__ \(\(visibility/){next;}' \
306+
-e 'if(/(.+?)\s*__attribute__ \(\(visibility/){print"$$1\n";$$blank=0;next;}' \
310307
-e 'if(/LT_OBJDIR/){print"/* This is ignored unless you are using libtool. */\n";}' \
311308
-e 'if(/^#define\s((?:HAVE|SUPPORT|STDC)_\w+)/){print"/* #undef $$1 */\n";$$blank=0;next;}' \
312309
-e 'if(/^#define\s(?!PACKAGE|VERSION)(\w+)/){print"#ifndef $$1\n$$_#endif\n";$$blank=0;next;}' \
@@ -518,7 +515,7 @@ if WITH_PCRE2_8
518515
lib_LTLIBRARIES += libpcre2-posix.la
519516
libpcre2_posix_la_SOURCES = src/pcre2posix.c
520517
libpcre2_posix_la_CFLAGS = \
521-
-DPCRE2_CODE_UNIT_WIDTH=8 \
518+
-DPCRE2_CODE_UNIT_WIDTH=8 @PCRE2POSIX_CFLAG@ \
522519
$(VISIBILITY_CFLAGS) $(AM_CFLAGS)
523520
libpcre2_posix_la_LDFLAGS = $(EXTRA_LIBPCRE2_POSIX_LDFLAGS)
524521
libpcre2_posix_la_LIBADD = libpcre2-8.la
@@ -570,7 +567,7 @@ if WITH_PCRE2_8
570567
TESTS += pcre2posix_test
571568
noinst_PROGRAMS += pcre2posix_test
572569
pcre2posix_test_SOURCES = src/pcre2posix_test.c
573-
pcre2posix_test_CFLAGS = $(AM_CFLAGS)
570+
pcre2posix_test_CFLAGS = $(AM_CFLAGS) @PCRE2POSIX_CFLAG@
574571
pcre2posix_test_LDADD = libpcre2-posix.la libpcre2-8.la
575572
endif # WITH_PCRE2_8
576573

NON-AUTOTOOLS-BUILD

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,8 @@ example.
159159
(7) If you want to build the POSIX wrapper functions (which apply only to the
160160
8-bit library), ensure that you have the src/pcre2posix.h file and then
161161
compile src/pcre2posix.c. Link the result (on its own) as the pcre2posix
162-
library.
162+
library. If targeting a DLL in Windows, make sure to include
163+
-DPCRE2POSIX_SHARED with your compiler flags.
163164

164165
(8) The pcre2test program can be linked with any combination of the 8-bit,
165166
16-bit and 32-bit libraries (depending on what you specfied in

config-cmake.h.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
#cmakedefine HAVE_BUILTIN_MUL_OVERFLOW 1
44
#cmakedefine HAVE_ATTRIBUTE_UNINITIALIZED 1
55
#cmakedefine HAVE_DIRENT_H 1
6-
#cmakedefine HAVE_STRERROR 1
76
#cmakedefine HAVE_SYS_STAT_H 1
87
#cmakedefine HAVE_SYS_TYPES_H 1
98
#cmakedefine HAVE_UNISTD_H 1
@@ -40,6 +39,7 @@
4039
#cmakedefine HEAP_MATCH_RECURSE 1
4140
#cmakedefine NEVER_BACKSLASH_C 1
4241

42+
#define PCRE2_EXPORT @PCRE2_EXPORT@
4343
#define LINK_SIZE @PCRE2_LINK_SIZE@
4444
#define HEAP_LIMIT @PCRE2_HEAP_LIMIT@
4545
#define MATCH_LIMIT @PCRE2_MATCH_LIMIT@

configure.ac

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,12 @@ if test "x$enable_shared" = "xno" ; then
640640
fi
641641
AC_SUBST(PCRE2_STATIC_CFLAG)
642642

643+
PCRE2POSIX_CFLAG=""
644+
if test "x$enable_shared" = "xyes" ; then
645+
PCRE2POSIX_CFLAG="-DPCRE2POSIX_SHARED"
646+
fi
647+
AC_SUBST(PCRE2POSIX_CFLAG)
648+
643649
# Here is where PCRE2-specific defines are handled
644650

645651
if test "$enable_pcre2_8" = "yes"; then
@@ -812,7 +818,7 @@ AC_DEFINE_UNQUOTED([MATCH_LIMIT], [$with_match_limit], [
812818
matching attempt. The value is also used to limit a loop counter in
813819
pcre2_dfa_match(). There is a runtime interface for setting a different
814820
limit. The limit exists in order to catch runaway regular expressions that
815-
take for ever to determine that they do not match. The default is set very
821+
take forever to determine that they do not match. The default is set very
816822
large so that it does not accidentally catch legitimate cases.])
817823

818824
# --with-match-limit-recursion is an obsolete synonym for --with-match-limit-depth
@@ -862,8 +868,9 @@ AH_VERBATIM([PCRE2_EXP_DEFN], [
862868
Win32, and it needs some magic to be inserted before the definition
863869
of a function that is exported by the library, define this macro to
864870
contain the relevant magic. If you do not define this macro, a suitable
865-
__declspec value is used for Windows systems; in other environments
866-
"extern" is used for a C compiler and "extern C" for a C++ compiler.
871+
__declspec value is used for Windows systems; in other environments
872+
a compiler relevant "extern" is used with any "visibility" related
873+
attributes from PCRE2_EXPORT included.
867874
This macro apears at the start of every exported function that is part
868875
of the external API. It does not appear on functions that are "external"
869876
in the C sense, but which are internal to the library. */

doc/pcre2posix.3

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.TH PCRE2POSIX 3 "26 April 2021" "PCRE2 10.37"
1+
.TH PCRE2POSIX 3 "13 May 2023" "PCRE2 10.43"
22
.SH NAME
33
PCRE2 - Perl-compatible regular expressions (revised API)
44
.SH "SYNOPSIS"
@@ -44,7 +44,12 @@ can be accessed by adding \fB-lpcre2-posix\fP to the command for linking an
4444
application. Because the POSIX functions call the native ones, it is also
4545
necessary to add \fB-lpcre2-8\fP.
4646
.P
47-
Although they were not defined as protypes in \fBpcre2posix.h\fP, releases
47+
On Windows systems, if you are linking to a DLL version of the library, it is
48+
recommended that \fBPCRE2POSIX_SHARED\fP is defined before including the
49+
\fBpcre2posix.h\fP header, as it will allow for a more efficient way to
50+
invoke the functions by adding the \fB__declspec(dllimport)\fP decorator.
51+
.P
52+
Although they were not defined as prototypes in \fBpcre2posix.h\fP, releases
4853
10.33 to 10.36 of the library contained functions with the POSIX names
4954
\fBregcomp()\fP etc. These simply passed their arguments to the PCRE2
5055
functions. These functions were provided for backwards compatibility with

libpcre2-posix.pc.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@ Name: libpcre2-posix
99
Description: Posix compatible interface to libpcre2-8
1010
Version: @PACKAGE_VERSION@
1111
Libs: -L${libdir} -lpcre2-posix@LIB_POSTFIX@
12-
Cflags: -I${includedir} @PCRE2_STATIC_CFLAG@
12+
Cflags: -I${includedir} @PCRE2POSIX_CFLAG@
1313
Requires.private: libpcre2-8

m4/pcre2_visibility.m4

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,9 @@ AC_DEFUN([PCRE2_VISIBILITY],
7373
VISIBILITY_CFLAGS="-fvisibility=hidden"
7474
VISIBILITY_CXXFLAGS="-fvisibility=hidden -fvisibility-inlines-hidden"
7575
HAVE_VISIBILITY=1
76-
AC_DEFINE(PCRE2_EXP_DECL, [extern __attribute__ ((visibility ("default")))], [to make a symbol visible])
77-
AC_DEFINE(PCRE2_EXP_DEFN, [__attribute__ ((visibility ("default")))], [to make a symbol visible])
78-
AC_DEFINE(PCRE2POSIX_EXP_DECL, [extern __attribute__ ((visibility ("default")))], [to make a symbol visible])
79-
AC_DEFINE(PCRE2POSIX_EXP_DEFN, [extern __attribute__ ((visibility ("default")))], [to make a symbol visible])
76+
AC_DEFINE(PCRE2_EXPORT, [__attribute__ ((visibility ("default")))], [to make a symbol visible])
77+
else
78+
AC_DEFINE(PCRE2_EXPORT, [], [to make a symbol visible])
8079
fi
8180
fi
8281
AC_SUBST([VISIBILITY_CFLAGS])

src/config.h.generic

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ sure both macros are undefined; an emulation function will then be used. */
184184
matching attempt. The value is also used to limit a loop counter in
185185
pcre2_dfa_match(). There is a runtime interface for setting a different
186186
limit. The limit exists in order to catch runaway regular expressions that
187-
take for ever to determine that they do not match. The default is set very
187+
take forever to determine that they do not match. The default is set very
188188
large so that it does not accidentally catch legitimate cases. */
189189
#ifndef MATCH_LIMIT
190190
#define MATCH_LIMIT 10000000
@@ -239,7 +239,7 @@ sure both macros are undefined; an emulation function will then be used. */
239239
#define PACKAGE_NAME "PCRE2"
240240

241241
/* Define to the full name and version of this package. */
242-
#define PACKAGE_STRING "PCRE2 10.42"
242+
#define PACKAGE_STRING "PCRE2 10.43-DEV"
243243

244244
/* Define to the one symbol short name of this package. */
245245
#define PACKAGE_TARNAME "pcre2"
@@ -248,7 +248,7 @@ sure both macros are undefined; an emulation function will then be used. */
248248
#define PACKAGE_URL ""
249249

250250
/* Define to the version of this package. */
251-
#define PACKAGE_VERSION "10.42"
251+
#define PACKAGE_VERSION "10.43-DEV"
252252

253253
/* The value of PARENS_NEST_LIMIT specifies the maximum depth of nested
254254
parentheses (of any kind) in a pattern. This limits the amount of system
@@ -278,12 +278,16 @@ sure both macros are undefined; an emulation function will then be used. */
278278
/* Define to any value to include debugging code. */
279279
/* #undef PCRE2_DEBUG */
280280

281+
/* to make a symbol visible */
282+
#define PCRE2_EXPORT
283+
281284
/* If you are compiling for a system other than a Unix-like system or
282285
Win32, and it needs some magic to be inserted before the definition
283286
of a function that is exported by the library, define this macro to
284287
contain the relevant magic. If you do not define this macro, a suitable
285-
__declspec value is used for Windows systems; in other environments
286-
"extern" is used for a C compiler and "extern C" for a C++ compiler.
288+
__declspec value is used for Windows systems; in other environments
289+
a compiler relevant "extern" is used with any "visibility" related
290+
attributes from PCRE2_EXPORT included.
287291
This macro apears at the start of every exported function that is part
288292
of the external API. It does not appear on functions that are "external"
289293
in the C sense, but which are internal to the library. */
@@ -441,7 +445,7 @@ sure both macros are undefined; an emulation function will then be used. */
441445
#endif
442446

443447
/* Version number of package */
444-
#define VERSION "10.42"
448+
#define VERSION "10.43-DEV"
445449

446450
/* Number of bits in a file offset, on hosts where this is settable. */
447451
/* #undef _FILE_OFFSET_BITS */

src/config.h.in

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ sure both macros are undefined; an emulation function will then be used. */
177177
matching attempt. The value is also used to limit a loop counter in
178178
pcre2_dfa_match(). There is a runtime interface for setting a different
179179
limit. The limit exists in order to catch runaway regular expressions that
180-
take for ever to determine that they do not match. The default is set very
180+
take forever to determine that they do not match. The default is set very
181181
large so that it does not accidentally catch legitimate cases. */
182182
#undef MATCH_LIMIT
183183

@@ -252,25 +252,20 @@ sure both macros are undefined; an emulation function will then be used. */
252252
allows for the buffering of "before" and "after" lines. */
253253
#undef PCRE2GREP_MAX_BUFSIZE
254254

255-
/* to make a symbol visible */
256-
#undef PCRE2POSIX_EXP_DECL
257-
258-
/* to make a symbol visible */
259-
#undef PCRE2POSIX_EXP_DEFN
260-
261255
/* Define to any value to include debugging code. */
262256
#undef PCRE2_DEBUG
263257

264258
/* to make a symbol visible */
265-
#undef PCRE2_EXP_DECL
259+
#undef PCRE2_EXPORT
266260

267261

268262
/* If you are compiling for a system other than a Unix-like system or
269263
Win32, and it needs some magic to be inserted before the definition
270264
of a function that is exported by the library, define this macro to
271265
contain the relevant magic. If you do not define this macro, a suitable
272-
__declspec value is used for Windows systems; in other environments
273-
"extern" is used for a C compiler and "extern C" for a C++ compiler.
266+
__declspec value is used for Windows systems; in other environments
267+
a compiler relevant "extern" is used with any "visibility" related
268+
attributes from PCRE2_EXPORT included.
274269
This macro apears at the start of every exported function that is part
275270
of the external API. It does not appear on functions that are "external"
276271
in the C sense, but which are internal to the library. */

src/pcre2_internal.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -119,20 +119,20 @@ only if it is not already set. */
119119
#ifndef PCRE2_EXP_DECL
120120
# ifdef _WIN32
121121
# ifndef PCRE2_STATIC
122-
# define PCRE2_EXP_DECL extern __declspec(dllexport)
123-
# define PCRE2_EXP_DEFN __declspec(dllexport)
122+
# define PCRE2_EXP_DECL extern __declspec(dllexport)
123+
# define PCRE2_EXP_DEFN __declspec(dllexport)
124124
# else
125-
# define PCRE2_EXP_DECL extern
125+
# define PCRE2_EXP_DECL extern PCRE2_EXPORT
126126
# define PCRE2_EXP_DEFN
127127
# endif
128128
# else
129129
# ifdef __cplusplus
130-
# define PCRE2_EXP_DECL extern "C"
130+
# define PCRE2_EXP_DECL extern "C" PCRE2_EXPORT
131131
# else
132-
# define PCRE2_EXP_DECL extern
132+
# define PCRE2_EXP_DECL extern PCRE2_EXPORT
133133
# endif
134134
# ifndef PCRE2_EXP_DEFN
135-
# define PCRE2_EXP_DEFN PCRE2_EXP_DECL
135+
# define PCRE2_EXP_DEFN PCRE2_EXP_DECL
136136
# endif
137137
# endif
138138
#endif

0 commit comments

Comments
 (0)