diff --git a/config/ext.json b/config/ext.json index 3134ab7bb..d4f8e6ce1 100644 --- a/config/ext.json +++ b/config/ext.json @@ -235,6 +235,18 @@ ], "lib-depends-windows": [] }, + "gmagick": { + "support": { + "Windows": "wip", + "BSD": "wip" + }, + "type": "external", + "source": "ext-gmagick", + "arg-type": "custom", + "lib-depends": [ + "graphicsmagick" + ] + }, "gmp": { "support": { "Windows": "wip", diff --git a/config/lib.json b/config/lib.json index 17258b771..41307ab40 100644 --- a/config/lib.json +++ b/config/lib.json @@ -197,6 +197,27 @@ "Security" ] }, + "graphicsmagick": { + "source": "graphicsmagick", + "pkg-configs": [ + "GraphicsMagick", + "GraphicsMagickWand" + ], + "lib-depends": [ + "zlib", + "libpng", + "libjpeg", + "bzip2", + "libxml2" + ], + "lib-suggests": [ + "libwebp", + "libtiff", + "freetype", + "zstd", + "xz" + ] + }, "grpc": { "source": "grpc", "pkg-configs": [ diff --git a/config/source.json b/config/source.json index d7224d4d6..c7c298db2 100644 --- a/config/source.json +++ b/config/source.json @@ -171,6 +171,16 @@ "path": "LICENSE" } }, + "ext-gmagick": { + "type": "url", + "url": "https://pecl.php.net/get/gmagick", + "path": "php-src/ext/gmagick", + "filename": "gmagick.tgz", + "license": { + "type": "file", + "path": "LICENSE" + } + }, "ext-gmssl": { "type": "ghtar", "repo": "gmssl/GmSSL-PHP", @@ -401,6 +411,14 @@ "path": "LICENSE" } }, + "graphicsmagick": { + "type": "url", + "url": "https://downloads.sourceforge.net/project/graphicsmagick/graphicsmagick/1.3.46/GraphicsMagick-1.3.46.tar.xz", + "license": { + "type": "file", + "path": "Copyright.txt" + } + }, "grpc": { "type": "git", "rev": "v1.75.x", diff --git a/src/SPC/builder/extension/gmagick.php b/src/SPC/builder/extension/gmagick.php new file mode 100644 index 000000000..9be1f158d --- /dev/null +++ b/src/SPC/builder/extension/gmagick.php @@ -0,0 +1,34 @@ +source_dir . '/gmagick.c', 'zend_exception_get_default()', 'zend_ce_exception'); + + // Remove the entire OpenMP check block from config.m4 to avoid linking + // against libgomp in static builds. gmagick's config.m4 uses PHP_CHECK_FUNC + // which does not honour ac_cv cache variables, so we must patch the source. + FileSystem::replaceFileRegex( + SOURCE_PATH . '/php-src/ext/gmagick/config.m4', + '/AC_MSG_CHECKING\(omp_pause_resource_all usability\).*?AC_MSG_RESULT\(no\)\n\t\t\]\)/s', + 'dnl OMP check removed for static build' + ); + return true; + } + + public function getUnixConfigureArg(bool $shared = false): string + { + return '--with-gmagick=' . ($shared ? 'shared,' : '') . BUILD_ROOT_PATH; + } +} diff --git a/src/SPC/builder/linux/library/graphicsmagick.php b/src/SPC/builder/linux/library/graphicsmagick.php new file mode 100644 index 000000000..abbd549c1 --- /dev/null +++ b/src/SPC/builder/linux/library/graphicsmagick.php @@ -0,0 +1,12 @@ +optionalLib('zlib', ...ac_with_args('zlib')) + ->optionalLib('libpng', ...ac_with_args('png')) + ->optionalLib('libjpeg', ...ac_with_args('jpeg')) + ->optionalLib('libwebp', ...ac_with_args('webp')) + ->optionalLib('libtiff', ...ac_with_args('tiff')) + ->optionalLib('freetype', ...ac_with_args('ttf')) + ->optionalLib('bzip2', ...ac_with_args('bzlib')) + ->addConfigureArgs( + '--disable-openmp', + '--without-x', + '--without-perl', + // HEIF/JXL: GraphicsMagick auto-detects libheif/libjxl from the + // buildroot but the API versions are often incompatible (e.g. + // GM 1.3.46 expects libheif symbols added in 2.4+). Exclude them + // to avoid compile errors. Neither format is needed for typical + // WordPress/web image processing (JPEG/PNG/WebP/GIF suffice). + '--without-heif', + '--without-jxl', + '--enable-shared=no', + '--enable-static=yes', + ); + + // special: linux-static target needs `-static` + $ldflags = SPCTarget::isStatic() ? '-static -ldl' : '-ldl'; + + // special: macOS needs -liconv + $libs = SPCTarget::getTargetOS() === 'Darwin' ? '-liconv' : ''; + + $ac->appendEnv([ + 'LDFLAGS' => $ldflags, + 'LIBS' => $libs, + 'PKG_CONFIG' => '$PKG_CONFIG --static', + ]); + + $ac->configure()->make(); + + $this->patchPkgconfPrefix(['GraphicsMagick.pc', 'GraphicsMagick++.pc', 'GraphicsMagickWand.pc']); + $this->patchLaDependencyPrefix(); + } +} diff --git a/src/globals/ext-tests/gmagick.php b/src/globals/ext-tests/gmagick.php new file mode 100644 index 000000000..aa98ff510 --- /dev/null +++ b/src/globals/ext-tests/gmagick.php @@ -0,0 +1,7 @@ +queryformats())); +assert(in_array('PNG', (new Gmagick())->queryformats())); diff --git a/src/globals/test-extensions.php b/src/globals/test-extensions.php index cbcecb0ee..f7a106a92 100644 --- a/src/globals/test-extensions.php +++ b/src/globals/test-extensions.php @@ -43,15 +43,16 @@ $upx = false; // whether to test frankenphp build, only available for macOS and linux -$frankenphp = false; +$frankenphp = true; // prefer downloading pre-built packages to speed up the build process $prefer_pre_built = false; // If you want to test your added extensions and libs, add below (comma separated, example `bcmath,openssl`). $extensions = match (PHP_OS_FAMILY) { - 'Linux', 'Darwin' => 'decimal', - 'Windows' => 'decimal', + 'Linux' => 'gmagick', + 'Darwin' => 'gmagick', + 'Windows' => 'gmagick', }; // If you want to test shared extensions, add them below (comma separated, example `bcmath,openssl`). @@ -66,7 +67,7 @@ // If you want to test extra libs for extensions, add them below (comma separated, example `libwebp,libavif`). Unnecessary, when $with_suggested_libs is true. $with_libs = match (PHP_OS_FAMILY) { - 'Linux', 'Darwin' => 'krb5', + 'Linux', 'Darwin' => '', 'Windows' => '', };