diff --git a/.github/workflows/dev.yml b/.github/workflows/dev.yml index eacc3c107..2b95e8189 100644 --- a/.github/workflows/dev.yml +++ b/.github/workflows/dev.yml @@ -242,9 +242,9 @@ jobs: maint/RunSymbolTest install-dir/usr/local/lib/ maint/ passenger: - # Tests with: Autoconf on oldest RHEL (in extended support). - # That's the absolute limit to how old a Linux version I'll tolerate regular testing on. - name: GCC, very old Autotools + # Tests on the oldest RHEL release in extended support with the minimum + # supported Autoconf version. + name: GCC, RHEL 8, minimum Autoconf runs-on: ubuntu-latest container: redhat/ubi8:8.6 if: github.event_name != 'workflow_dispatch' || (inputs.job_id == 'all' || inputs.job_id == 'passenger') @@ -252,9 +252,23 @@ jobs: - name: Setup run: | yum -q makecache - yum -q install -y gcc git make automake autoconf libtool diffutils file glibc-langpack-en + yum -q install -y gcc git make automake libtool diffutils file glibc-langpack-en m4 perl curl xz yum -q update -y glibc-common + - name: Install Autoconf 2.71 + run: | + curl --fail --location --retry 3 --output "$RUNNER_TEMP/autoconf-2.71.tar.xz" \ + https://ftp.gnu.org/gnu/autoconf/autoconf-2.71.tar.xz + printf '%s %s\n' \ + f14c83cfebcc9427f2c3cea7258bd90df972d92eb26752da4ddad81c87a0faa4 \ + "$RUNNER_TEMP/autoconf-2.71.tar.xz" | sha256sum --check --status + tar -C "$RUNNER_TEMP" -xf "$RUNNER_TEMP/autoconf-2.71.tar.xz" + pushd "$RUNNER_TEMP/autoconf-2.71" + ./configure --prefix="$RUNNER_TEMP/autoconf-prefix" + make -j"$(nproc)" install + popd + echo "$RUNNER_TEMP/autoconf-prefix/bin" >> "$GITHUB_PATH" + - name: Checkout uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: diff --git a/BUILD.bazel b/BUILD.bazel index 1d7912916..147d20ec0 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -27,7 +27,7 @@ LOCAL_DEFINES = [ "SUPPORT_UNICODE", ] + select({ "@platforms//os:windows": [], - "//conditions:default": ["HAVE_UNISTD_H"], + "//conditions:default": ["HAVE_UNISTD_H", "HAVE_STDATOMIC_H"], }) # Workaround for a Bazel quirk. It is extremely strict about the #include path diff --git a/CMakeLists.txt b/CMakeLists.txt index 38c190337..ee2095995 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -110,7 +110,13 @@ message(STATUS "Using CMake version ${CMAKE_VERSION} (${CMAKE_COMMAND})") # Increased minimum to 3.15 to allow use of string(REPEAT). cmake_minimum_required(VERSION 3.15 FATAL_ERROR) project(PCRE2 C) -set(CMAKE_C_STANDARD 99) +if("c_std_11" IN_LIST CMAKE_C_COMPILE_FEATURES) + set(CMAKE_C_STANDARD 11) +elseif("c_std_99" IN_LIST CMAKE_C_COMPILE_FEATURES) + set(CMAKE_C_STANDARD 99) +else() + message(FATAL_ERROR "C compiler must support at least C99.") +endif() set(CMAKE_C_STANDARD_REQUIRED TRUE) set(CMAKE_C_VISIBILITY_PRESET hidden) @@ -190,11 +196,26 @@ check_symbol_exists(secure_getenv "stdlib.h" HAVE_SECURE_GETENV) # glibc 2.17 check_symbol_exists(setrlimit "sys/resource.h" HAVE_SETRLIMIT) cmake_pop_check_state() +check_c_source_compiles( + [=[ + #ifdef __STDC_NO_ATOMICS__ + #error "C compiler does not support standard C atomics" + #endif + #include + int main(void) { + atomic_int value; + atomic_init(&value, 0); + return atomic_load(&value); + } + ]=] + HAVE_STDATOMIC_H +) + check_c_source_compiles( [=[ #include #include - int main(int c, char *v[]) { char buf[PATH_MAX]; realpath(v[c], buf); return 0; } + int main(int c, char *v[]) { char buf[PATH_MAX]; return realpath(v[c], buf) == NULL; } ]=] HAVE_REALPATH ) diff --git a/build.zig b/build.zig index 61a13f23c..341981bc6 100644 --- a/build.zig +++ b/build.zig @@ -60,9 +60,14 @@ pub fn build(b: *std.Build) !void { const is_glibc = rt.isGnuLibC(); const is_freebsd = rt.isFreeBSDLibC(); - const cflags = &.{ + const common_cflags: []const []const u8 = &.{ + "-std=c11", "-fvisibility=hidden", }; + const cflags: []const []const u8 = if (rt.os.tag == .linux) + try std.mem.concat(b.allocator, []const u8, &.{ common_cflags, &.{"-D_GNU_SOURCE"} }) + else + common_cflags; const config_h = b.addConfigHeader( .{ @@ -82,6 +87,7 @@ pub fn build(b: *std.Build) !void { .HAVE_SYS_TYPES_H = true, .HAVE_UNISTD_H = is_unix or is_mingw, .HAVE_WINDOWS_H = rt.os.tag == .windows, + .HAVE_STDATOMIC_H = true, .HAVE_MEMFD_CREATE = is_musl or is_glibc or is_freebsd, .HAVE_SECURE_GETENV = is_musl or is_glibc or is_freebsd, diff --git a/configure.ac b/configure.ac index 2e3d7feda..8c8332fb6 100644 --- a/configure.ac +++ b/configure.ac @@ -19,7 +19,7 @@ m4_define(libpcre2_16_version, [16:0:16]) m4_define(libpcre2_32_version, [16:0:16]) m4_define(libpcre2_posix_version, [3:8:0]) -AC_PREREQ([2.69]) +AC_PREREQ([2.71]) AC_INIT([PCRE2],pcre2_major.pcre2_minor[]pcre2_prerelease,[],[pcre2]) AC_CONFIG_SRCDIR([src/pcre2.h.in]) AM_INIT_AUTOMAKE([dist-bzip2 dist-zip foreign]) @@ -48,7 +48,8 @@ AC_CONFIG_MACRO_DIR([m4]) remember_set_CFLAGS="$CFLAGS" -m4_version_prereq(2.70, [AC_PROG_CC], [AC_PROG_CC_C99]) +AC_PROG_CC +AS_CASE([$ac_prog_cc_stdc], [c89|no], [AC_MSG_FAILURE([C compiler does not support C99])]) AM_PROG_CC_C_O AC_USE_SYSTEM_EXTENSIONS @@ -92,17 +93,17 @@ PCRE2_CHECK_VSCRIPT # Check for Clang __attribute__((uninitialized)) feature -AC_MSG_CHECKING([for __attribute__((uninitialized))]) AC_LANG_PUSH([C]) tmp_CFLAGS=$CFLAGS if test $WORKING_WERROR -eq 1; then CFLAGS="$CFLAGS -Werror" fi -AC_COMPILE_IFELSE([AC_LANG_PROGRAM(, - [[char buf[128] __attribute__((uninitialized));(void)buf]])], - [pcre2_cc_cv_attribute_uninitialized=yes], - [pcre2_cc_cv_attribute_uninitialized=no]) -AC_MSG_RESULT([$pcre2_cc_cv_attribute_uninitialized]) +AC_CACHE_CHECK([for __attribute__((uninitialized))], [pcre2_cc_cv_attribute_uninitialized], [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM(, + [[char buf[128] __attribute__((uninitialized));(void)buf]])], + [pcre2_cc_cv_attribute_uninitialized=yes], + [pcre2_cc_cv_attribute_uninitialized=no]) +]) if test "$pcre2_cc_cv_attribute_uninitialized" = yes; then AC_DEFINE([HAVE_ATTRIBUTE_UNINITIALIZED], 1, [Define this if your compiler supports __attribute__((uninitialized))]) @@ -112,12 +113,12 @@ AC_LANG_POP([C]) # Check for the assume() builtin -AC_MSG_CHECKING([for __assume()]) AC_LANG_PUSH([C]) -AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[__assume(1)]])], - [pcre2_cc_cv_builtin_assume=yes], - [pcre2_cc_cv_builtin_assume=no]) -AC_MSG_RESULT([$pcre2_cc_cv_builtin_assume]) +AC_CACHE_CHECK([for __assume()], [pcre2_cc_cv_builtin_assume], [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[__assume(1)]])], + [pcre2_cc_cv_builtin_assume=yes], + [pcre2_cc_cv_builtin_assume=no]) +]) if test "$pcre2_cc_cv_builtin_assume" = yes; then AC_DEFINE([HAVE_BUILTIN_ASSUME], 1, [Define this if your compiler provides __assume()]) @@ -126,34 +127,34 @@ AC_LANG_POP([C]) # Check for the mul_overflow() builtin -AC_MSG_CHECKING([for __builtin_mul_overflow()]) AC_LANG_PUSH([C]) -AC_LINK_IFELSE([AC_LANG_PROGRAM([[ - #ifdef HAVE_SYS_TYPES_H - #include - #endif - #include - - int a, b; - size_t m; - ]], [[__builtin_mul_overflow(a, b, &m)]])], - [pcre2_cc_cv_builtin_mul_overflow=yes], - [pcre2_cc_cv_builtin_mul_overflow=no]) -AC_MSG_RESULT([$pcre2_cc_cv_builtin_mul_overflow]) +AC_CACHE_CHECK([for __builtin_mul_overflow()], [pcre2_cc_cv_builtin_mul_overflow], [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + #ifdef HAVE_SYS_TYPES_H + #include + #endif + #include + + int a, b; + size_t m; + ]], [[__builtin_mul_overflow(a, b, &m)]])], + [pcre2_cc_cv_builtin_mul_overflow=yes], + [pcre2_cc_cv_builtin_mul_overflow=no]) +]) if test "$pcre2_cc_cv_builtin_mul_overflow" = yes; then - AC_DEFINE([HAVE_BUILTIN_MUL_OVERFLOW], 1, - [Define this if your compiler provides __builtin_mul_overflow()]) + AC_DEFINE([HAVE_BUILTIN_MUL_OVERFLOW], 1, + [Define this if your compiler provides __builtin_mul_overflow()]) fi AC_LANG_POP([C]) # Check for the unreachable() builtin -AC_MSG_CHECKING([for __builtin_unreachable()]) AC_LANG_PUSH([C]) -AC_LINK_IFELSE([AC_LANG_PROGRAM([[int r;]], [[if (r) __builtin_unreachable()]])], - [pcre2_cc_cv_builtin_unreachable=yes], - [pcre2_cc_cv_builtin_unreachable=no]) -AC_MSG_RESULT([$pcre2_cc_cv_builtin_unreachable]) +AC_CACHE_CHECK([for __builtin_unreachable()], [pcre2_cc_cv_builtin_unreachable], [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[int r;]], [[if (r) __builtin_unreachable()]])], + [pcre2_cc_cv_builtin_unreachable=yes], + [pcre2_cc_cv_builtin_unreachable=no]) +]) if test "$pcre2_cc_cv_builtin_unreachable" = yes; then AC_DEFINE([HAVE_BUILTIN_UNREACHABLE], 1, [Define this if your compiler provides __builtin_unreachable()]) @@ -233,17 +234,21 @@ AC_ARG_ENABLE(jit, # This code enables JIT if the hardware supports it. if test "$enable_jit" = "auto"; then - AC_LANG(C) + AC_LANG_PUSH([C]) SAVE_CPPFLAGS=$CPPFLAGS - CPPFLAGS=-I$srcdir - AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ - #define SLJIT_CONFIG_AUTO 1 - #include "deps/sljit/sljit_src/sljitConfigCPU.h" - #if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) - #error unsupported - #endif]])], enable_jit=yes, enable_jit=no) + CPPFLAGS="$CPPFLAGS -I$srcdir" + AC_CACHE_CHECK([whether JIT is supported on this hardware], [pcre2_cv_jit_supported], [ + AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ + #define SLJIT_CONFIG_AUTO 1 + #include "deps/sljit/sljit_src/sljitConfigCPU.h" + #if (defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED) + #error unsupported + #endif]] + )], [pcre2_cv_jit_supported=yes], [pcre2_cv_jit_supported=no]) + ]) CPPFLAGS=$SAVE_CPPFLAGS - echo checking for JIT support on this hardware... $enable_jit + AC_LANG_POP([C]) + enable_jit=$pcre2_cv_jit_supported fi # Handle --enable-jit-sealloc (disabled by default and only experimental) @@ -619,25 +624,47 @@ fi # Checks for typedefs, structures, and compiler characteristics. -AC_C_CONST AC_TYPE_SIZE_T # Checks for library functions. AC_CHECK_FUNCS(memfd_create mkostemp secure_getenv setrlimit) -AC_MSG_CHECKING([for realpath]) -AC_LINK_IFELSE([AC_LANG_PROGRAM([[ -#include -#include -]],[[ -char buffer[PATH_MAX]; -realpath(".", buffer); -]])], -[AC_MSG_RESULT([yes]) - AC_DEFINE([HAVE_REALPATH], 1, - [Define to 1 if you have the `realpath' function.]) -], -AC_MSG_RESULT([no])) + +AC_LANG_PUSH([C]) +AC_CACHE_CHECK([for standard C atomics], [pcre2_cv_c_atomics], [ + AC_LINK_IFELSE([ + AC_LANG_SOURCE([[ + #ifdef __STDC_NO_ATOMICS__ + #error "C compiler does not support standard C atomics" + #endif + #include + int main(void) { + atomic_int value; + atomic_init(&value, 0); + return atomic_load(&value); + } + ]]) + ], [pcre2_cv_c_atomics=yes], [pcre2_cv_c_atomics=no]) +]) +AS_IF([test "$pcre2_cv_c_atomics" = yes], [ + AC_DEFINE([HAVE_STDATOMIC_H], 1, [Define to 1 if stardard (C11 or later) atomics are available.]) +]) +AC_LANG_POP([C]) + +AC_LANG_PUSH([C]) +AC_CACHE_CHECK([for realpath], [pcre2_cv_func_realpath], [ + AC_LINK_IFELSE([ + AC_LANG_SOURCE([[ + #include + #include + int main(int c, char *v[]) { char buf[PATH_MAX]; return realpath(v[c], buf) == NULL; } + ]]) + ], [pcre2_cv_func_realpath=yes], [pcre2_cv_func_realpath=no]) +]) +AS_IF([test "$pcre2_cv_func_realpath" = yes], [ + AC_DEFINE([HAVE_REALPATH], 1, [Define to 1 if you have the `realpath' function.]) +]) +AC_LANG_POP([C]) # Check for the availability of libz (aka zlib) @@ -666,17 +693,20 @@ AC_CHECK_HEADERS([bzlib.h], [HAVE_BZLIB_H=1]) # # Custom test follows -AC_MSG_CHECKING([for libbz2]) -OLD_LIBS="$LIBS" -LIBS="$LIBS -lbz2" -AC_LINK_IFELSE([AC_LANG_PROGRAM([[ -#ifdef HAVE_BZLIB_H -#include -#endif]], -[[return (int)BZ2_bzopen("conftest", "rb");]])], -[AC_MSG_RESULT([yes]);HAVE_LIBBZ2=1; break;], -AC_MSG_RESULT([no])) -LIBS="$OLD_LIBS" +AC_LANG_PUSH([C]) +AC_CACHE_CHECK([for libbz2], [pcre2_cv_lib_bz2], [ + OLD_LIBS="$LIBS" + LIBS="$LIBS -lbz2" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + #ifdef HAVE_BZLIB_H + #include + #endif]], + [[return (int)BZ2_bzopen("conftest", "rb");]]) + ], [pcre2_cv_lib_bz2=yes], [pcre2_cv_lib_bz2=no]) + LIBS="$OLD_LIBS" +]) +AS_IF([test "$pcre2_cv_lib_bz2" = yes], [HAVE_LIBBZ2=1]) +AC_LANG_POP([C]) # Check for the availability of libreadline @@ -1180,15 +1210,16 @@ fi # enable_coverage AM_CONDITIONAL([WITH_GCOV],[test "x$enable_coverage" = "xyes"]) -AC_MSG_CHECKING([whether Intel CET is enabled]) AC_LANG_PUSH([C]) -AC_COMPILE_IFELSE([AC_LANG_PROGRAM(, - [[#ifndef __CET__ -# error CET is not enabled -#endif]])], - [pcre2_cc_cv_intel_cet_enabled=yes], - [pcre2_cc_cv_intel_cet_enabled=no]) -AC_MSG_RESULT([$pcre2_cc_cv_intel_cet_enabled]) +AC_CACHE_CHECK([whether Intel CET is enabled], [pcre2_cc_cv_intel_cet_enabled], [ + AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ + #ifndef __CET__ + # error CET is not enabled + #endif + ]])], + [pcre2_cc_cv_intel_cet_enabled=yes], + [pcre2_cc_cv_intel_cet_enabled=no]) +]) if test "$pcre2_cc_cv_intel_cet_enabled" = yes; then CET_CFLAGS="-mshstk" AC_SUBST([CET_CFLAGS]) @@ -1211,18 +1242,18 @@ AC_SUBST([PCRE2_EXTRA_LOCAL_SYMS]) # Produce these files, in addition to config.h. AC_CONFIG_FILES( - Makefile - libpcre2-8.pc - libpcre2-16.pc - libpcre2-32.pc - libpcre2-posix.pc - pcre2-config - src/pcre2.h - src/libpcre2-8.sym - src/libpcre2-16.sym - src/libpcre2-32.sym - src/libpcre2-posix.sym -) + Makefile + libpcre2-8.pc + libpcre2-16.pc + libpcre2-32.pc + libpcre2-posix.pc + pcre2-config + src/pcre2.h + src/libpcre2-8.sym + src/libpcre2-16.sym + src/libpcre2-32.sym + src/libpcre2-posix.sym + ) # Make the generated script files executable. AC_CONFIG_COMMANDS([script-chmod], [chmod a+x pcre2-config]) diff --git a/m4/pcre2_visibility.m4 b/m4/pcre2_visibility.m4 index 1e4e81952..fefcb0d93 100644 --- a/m4/pcre2_visibility.m4 +++ b/m4/pcre2_visibility.m4 @@ -21,6 +21,7 @@ dnl Refactored to work with non GCC (but compatible) compilers. AC_DEFUN([PCRE2_VISIBILITY], [ AC_REQUIRE([AC_PROG_CC]) + AC_LANG_PUSH([C]) VISIBILITY_CFLAGS= HAVE_VISIBILITY=0 dnl First, check whether -Werror can be added to the command line, or @@ -59,8 +60,8 @@ AC_DEFUN([PCRE2_VISIBILITY], dnl at the first function definition in every compilation unit, and we dnl don't want to use the option in this case. AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[extern __attribute__((__visibility__("hidden"))) int hiddenfunc (void); + [AC_LANG_PROGRAM([[ + extern __attribute__((__visibility__("hidden"))) int hiddenfunc (void); extern __attribute__((__visibility__("default"))) int exportedfunc (void); void dummyfunc (void) {} ]], @@ -82,4 +83,5 @@ AC_DEFUN([PCRE2_VISIBILITY], AC_SUBST([HAVE_VISIBILITY]) AC_DEFINE_UNQUOTED([HAVE_VISIBILITY], [$HAVE_VISIBILITY], [Define to 1 if the compiler supports GCC compatible visibility declarations.]) + AC_LANG_POP([C]) ]) diff --git a/m4/pcre2_zos.m4 b/m4/pcre2_zos.m4 index 2e5dbd48b..f592eb329 100644 --- a/m4/pcre2_zos.m4 +++ b/m4/pcre2_zos.m4 @@ -7,6 +7,7 @@ dnl Bruno Haible). AC_DEFUN([PCRE2_ZOS_FIXES], [ + AC_LANG_PUSH([C]) AC_CACHE_CHECK([for OS/390 (z/OS)], [pcre2_cv_os390], [if test "`uname`" = "OS/390"; then pcre2_cv_os390=yes @@ -47,4 +48,5 @@ AC_DEFUN([PCRE2_ZOS_FIXES], fi fi + AC_LANG_POP([C]) ]) diff --git a/src/config-cmake.h.in b/src/config-cmake.h.in index d8300d855..c96213e04 100644 --- a/src/config-cmake.h.in +++ b/src/config-cmake.h.in @@ -10,6 +10,7 @@ #cmakedefine HAVE_SYS_TYPES_H 1 #cmakedefine HAVE_UNISTD_H 1 #cmakedefine HAVE_WINDOWS_H 1 +#cmakedefine HAVE_STDATOMIC_H 1 #cmakedefine HAVE_MEMFD_CREATE 1 #cmakedefine HAVE_SECURE_GETENV 1 diff --git a/src/config.h.generic b/src/config.h.generic index 21629fb22..1aef78fb9 100644 --- a/src/config.h.generic +++ b/src/config.h.generic @@ -122,6 +122,9 @@ surrounded by #ifndef/#endif lines so that the value can be overridden by -D. */ /* Define to 1 if you have the `setrlimit' function. */ /* #undef HAVE_SETRLIMIT */ +/* Define to 1 if stardard (C11 or later) atomics are available. */ +/* #undef HAVE_STDATOMIC_H */ + /* Define to 1 if you have the header file. */ /* #undef HAVE_STDINT_H */ @@ -486,9 +489,6 @@ surrounded by #ifndef/#endif lines so that the value can be overridden by -D. */ /* Define for large files, on AIX-style hosts. */ /* #undef _LARGE_FILES */ -/* Define to empty if `const' does not conform to ANSI C. */ -/* #undef const */ - /* Define to the type of a signed integer type of width exactly 64 bits if such a type exists and the standard includes do not define it. */ /* #undef int64_t */ diff --git a/vms/configure.com b/vms/configure.com index 235647867..dcb16da89 100644 --- a/vms/configure.com +++ b/vms/configure.com @@ -549,6 +549,9 @@ surrounded by #ifndef/#endif lines so that the value can be overridden by -D. */ /* Define to 1 if you have the 'secure_getenv' function. */ #undef HAVE_SECURE_GETENV +/* Define to 1 if you have the header file. */ +#undef HAVE_STDATOMIC_H + /* Define to 1 if you have the header file. */ #define HAVE_STDINT_H 1