From f08dc82d066b600cff73720cd040e5d7d50c36eb Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Mon, 6 Sep 2021 10:57:56 +0200 Subject: [PATCH] Ensure extension is linked with -Wl,-z,nodelete See: https://github.com/libvips/php-vips-ext/issues/43. --- .gitattributes | 1 + config.m4 | 9 +++++++ m4/ax_append_flag.m4 | 50 +++++++++++++++++++++++++++++++++++ m4/ax_append_link_flags.m4 | 44 +++++++++++++++++++++++++++++++ m4/ax_check_link_flag.m4 | 53 ++++++++++++++++++++++++++++++++++++++ m4/ax_require_defined.m4 | 37 ++++++++++++++++++++++++++ package.xml | 7 +++++ vips.c | 36 -------------------------- 8 files changed, 201 insertions(+), 36 deletions(-) create mode 100644 .gitattributes create mode 100644 m4/ax_append_flag.m4 create mode 100644 m4/ax_append_link_flags.m4 create mode 100644 m4/ax_check_link_flag.m4 create mode 100644 m4/ax_require_defined.m4 diff --git a/config.m4 b/config.m4 index 729cc25..b72931e 100644 --- a/config.m4 +++ b/config.m4 @@ -1,6 +1,11 @@ dnl $Id$ dnl config.m4 for extension vips +m4_include(m4/ax_require_defined.m4) +m4_include(m4/ax_append_flag.m4) +m4_include(m4/ax_check_link_flag.m4) +m4_include(m4/ax_append_link_flags.m4) + PHP_ARG_WITH(vips, for vips support, [ --with-vips Include vips support]) @@ -35,6 +40,10 @@ if test x"$PHP_VIPS" != x"no"; then ],[$VIPS_LIBS] ) + # Mark DSO non-deletable at runtime. + # See: https://github.com/libvips/php-vips-ext/issues/43 + AX_APPEND_LINK_FLAGS([-Wl,-z,nodelete]) + AC_DEFINE(HAVE_VIPS, 1, [Whether you have vips]) PHP_NEW_EXTENSION(vips, vips.c, $ext_shared,, -DZEND_ENABLE_STATIC_TSRMLS_CACHE=1 $VIPS_CFLAGS) PHP_SUBST(VIPS_SHARED_LIBADD) diff --git a/m4/ax_append_flag.m4 b/m4/ax_append_flag.m4 new file mode 100644 index 0000000..dd6d8b6 --- /dev/null +++ b/m4/ax_append_flag.m4 @@ -0,0 +1,50 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_append_flag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE]) +# +# DESCRIPTION +# +# FLAG is appended to the FLAGS-VARIABLE shell variable, with a space +# added in between. +# +# If FLAGS-VARIABLE is not specified, the current language's flags (e.g. +# CFLAGS) is used. FLAGS-VARIABLE is not changed if it already contains +# FLAG. If FLAGS-VARIABLE is unset in the shell, it is set to exactly +# FLAG. +# +# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# Copyright (c) 2011 Maarten Bosmans +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 8 + +AC_DEFUN([AX_APPEND_FLAG], +[dnl +AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_SET_IF +AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])]) +AS_VAR_SET_IF(FLAGS,[ + AS_CASE([" AS_VAR_GET(FLAGS) "], + [*" $1 "*], [AC_RUN_LOG([: FLAGS already contains $1])], + [ + AS_VAR_APPEND(FLAGS,[" $1"]) + AC_RUN_LOG([: FLAGS="$FLAGS"]) + ]) + ], + [ + AS_VAR_SET(FLAGS,[$1]) + AC_RUN_LOG([: FLAGS="$FLAGS"]) + ]) +AS_VAR_POPDEF([FLAGS])dnl +])dnl AX_APPEND_FLAG diff --git a/m4/ax_append_link_flags.m4 b/m4/ax_append_link_flags.m4 new file mode 100644 index 0000000..99b9fa5 --- /dev/null +++ b/m4/ax_append_link_flags.m4 @@ -0,0 +1,44 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_append_link_flags.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_APPEND_LINK_FLAGS([FLAG1 FLAG2 ...], [FLAGS-VARIABLE], [EXTRA-FLAGS], [INPUT]) +# +# DESCRIPTION +# +# For every FLAG1, FLAG2 it is checked whether the linker works with the +# flag. If it does, the flag is added FLAGS-VARIABLE +# +# If FLAGS-VARIABLE is not specified, the linker's flags (LDFLAGS) is +# used. During the check the flag is always added to the linker's flags. +# +# If EXTRA-FLAGS is defined, it is added to the linker's default flags +# when the check is done. The check is thus made with the flags: "LDFLAGS +# EXTRA-FLAGS FLAG". This can for example be used to force the linker to +# issue an error when a bad flag is given. +# +# INPUT gives an alternative input source to AC_COMPILE_IFELSE. +# +# NOTE: This macro depends on the AX_APPEND_FLAG and AX_CHECK_LINK_FLAG. +# Please keep this macro in sync with AX_APPEND_COMPILE_FLAGS. +# +# LICENSE +# +# Copyright (c) 2011 Maarten Bosmans +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 7 + +AC_DEFUN([AX_APPEND_LINK_FLAGS], +[AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG]) +AX_REQUIRE_DEFINED([AX_APPEND_FLAG]) +for flag in $1; do + AX_CHECK_LINK_FLAG([$flag], [AX_APPEND_FLAG([$flag], [m4_default([$2], [LDFLAGS])])], [], [$3], [$4]) +done +])dnl AX_APPEND_LINK_FLAGS diff --git a/m4/ax_check_link_flag.m4 b/m4/ax_check_link_flag.m4 new file mode 100644 index 0000000..03a30ce --- /dev/null +++ b/m4/ax_check_link_flag.m4 @@ -0,0 +1,53 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_check_link_flag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CHECK_LINK_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) +# +# DESCRIPTION +# +# Check whether the given FLAG works with the linker or gives an error. +# (Warnings, however, are ignored) +# +# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on +# success/failure. +# +# If EXTRA-FLAGS is defined, it is added to the linker's default flags +# when the check is done. The check is thus made with the flags: "LDFLAGS +# EXTRA-FLAGS FLAG". This can for example be used to force the linker to +# issue an error when a bad flag is given. +# +# INPUT gives an alternative input source to AC_LINK_IFELSE. +# +# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this +# macro in sync with AX_CHECK_{PREPROC,COMPILE}_FLAG. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# Copyright (c) 2011 Maarten Bosmans +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 6 + +AC_DEFUN([AX_CHECK_LINK_FLAG], +[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF +AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_ldflags_$4_$1])dnl +AC_CACHE_CHECK([whether the linker accepts $1], CACHEVAR, [ + ax_check_save_flags=$LDFLAGS + LDFLAGS="$LDFLAGS $4 $1" + AC_LINK_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], + [AS_VAR_SET(CACHEVAR,[yes])], + [AS_VAR_SET(CACHEVAR,[no])]) + LDFLAGS=$ax_check_save_flags]) +AS_VAR_IF(CACHEVAR,yes, + [m4_default([$2], :)], + [m4_default([$3], :)]) +AS_VAR_POPDEF([CACHEVAR])dnl +])dnl AX_CHECK_LINK_FLAGS diff --git a/m4/ax_require_defined.m4 b/m4/ax_require_defined.m4 new file mode 100644 index 0000000..17c3eab --- /dev/null +++ b/m4/ax_require_defined.m4 @@ -0,0 +1,37 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_require_defined.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_REQUIRE_DEFINED(MACRO) +# +# DESCRIPTION +# +# AX_REQUIRE_DEFINED is a simple helper for making sure other macros have +# been defined and thus are available for use. This avoids random issues +# where a macro isn't expanded. Instead the configure script emits a +# non-fatal: +# +# ./configure: line 1673: AX_CFLAGS_WARN_ALL: command not found +# +# It's like AC_REQUIRE except it doesn't expand the required macro. +# +# Here's an example: +# +# AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG]) +# +# LICENSE +# +# Copyright (c) 2014 Mike Frysinger +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 2 + +AC_DEFUN([AX_REQUIRE_DEFINED], [dnl + m4_ifndef([$1], [m4_fatal([macro ]$1[ is not defined; is a m4 file missing?])]) +])dnl AX_REQUIRE_DEFINED diff --git a/vips.c b/vips.c index 33b47d4..2e96aad 100644 --- a/vips.c +++ b/vips.c @@ -13,7 +13,6 @@ #include "php.h" #include "php_ini.h" #include "ext/standard/info.h" -#include "SAPI.h" #include "php_vips.h" #include @@ -2007,41 +2006,6 @@ static void php_free_gobject(zend_resource *rsrc) */ PHP_MINIT_FUNCTION(vips) { - if (strcmp(sapi_module.name, "apache2handler") == 0) { - /* "apachectl graceful" can cause us terrible problems. What happens: - * - * - the main apache process unloads this extension, vips.so - * - in turn, the C runtime will unload libvips.so, the vips library, - * since vips.so is the only thing that references it - * - libvips.so in turn uses glib.so, but this is often not unloaded, - * since other parts of apache can be using it (glib could also - * possibly be preventing unload itself, I'm not sure) - * - the main apache process then reloads vips.so, which in turn will - * reload libvips.so as it starts up - * - vips.so tries to init libvips.so - * - libvips.so tries to register its types (such as VipsImage) with - * glib.so, but finds the types from the previous init still there - * - everything breaks - * - * A simple fix that will always work is just to lock libvips in - * memory and prevent unload. We intentionally leak refs to the shared - * library. - * - * We include the binary API version number that this extension needs. - * We can't just load .so, that's only installed with libvips-dev, - * which may not be present at runtime. - */ -#ifdef VIPS_SONAME - if (!dlopen(VIPS_SONAME, RTLD_LAZY | RTLD_NODELETE)) -#else /*!VIPS_SONAME*/ - if (!dlopen("libvips.so.42", RTLD_LAZY | RTLD_NODELETE)) -#endif /*VIPS_SONAME*/ - { - sapi_module.sapi_error(E_WARNING, "php-vips-ext: unable to lock " - "libvips -- graceful may be unreliable"); - } - } - /* If you have INI entries, uncomment these lines REGISTER_INI_ENTRIES(); */