From 7527f9f0994617484b0d56e27b5878ec67643c3b Mon Sep 17 00:00:00 2001 From: crazywhalecc Date: Wed, 10 May 2023 02:04:08 +0800 Subject: [PATCH] add imagemagick (imagick) for macos, pkg-config for unix.= --- config/lib.json | 6 +- ext-support.md | 3 +- src/SPC/builder/BuilderBase.php | 3 + src/SPC/builder/LibraryBase.php | 6 ++ src/SPC/builder/extension/imagick.php | 17 ++++++ src/SPC/builder/linux/LinuxBuilder.php | 7 ++- src/SPC/builder/linux/SystemUtil.php | 2 +- .../linux/library/LinuxLibraryBase.php | 5 ++ src/SPC/builder/linux/library/libpng.php | 1 + src/SPC/builder/linux/library/pkgconfig.php | 15 +++++ src/SPC/builder/macos/MacOSBuilder.php | 3 +- src/SPC/builder/macos/library/imagemagick.php | 60 +++++++++++++++++++ src/SPC/builder/macos/library/libpng.php | 1 + src/SPC/builder/macos/library/pkgconfig.php | 15 +++++ src/SPC/builder/traits/UnixLibraryTrait.php | 16 +++++ .../builder/traits/UnixSystemUtilTrait.php | 1 + src/SPC/builder/unix/library/freetype.php | 10 ++++ src/SPC/builder/unix/library/libavif.php | 1 + src/SPC/builder/unix/library/libjpeg.php | 1 + src/SPC/builder/unix/library/libwebp.php | 1 + src/SPC/builder/unix/library/libzip.php | 4 +- src/SPC/builder/unix/library/pkgconfig.php | 43 +++++++++++++ src/SPC/store/SourcePatcher.php | 9 +++ src/globals/functions.php | 10 +++- 24 files changed, 229 insertions(+), 11 deletions(-) create mode 100644 src/SPC/builder/extension/imagick.php create mode 100644 src/SPC/builder/linux/library/pkgconfig.php create mode 100644 src/SPC/builder/macos/library/imagemagick.php create mode 100644 src/SPC/builder/macos/library/pkgconfig.php create mode 100644 src/SPC/builder/unix/library/pkgconfig.php diff --git a/config/lib.json b/config/lib.json index b3e86165..466763b8 100644 --- a/config/lib.json +++ b/config/lib.json @@ -107,11 +107,11 @@ "zlib", "libpng", "libjpeg", - "bzip2" + "bzip2", + "libwebp", + "freetype" ], "lib-suggests": [ - "libwebp", - "freetype", "zstd", "xz", "libzip", diff --git a/ext-support.md b/ext-support.md index afdccdf0..a744794b 100644 --- a/ext-support.md +++ b/ext-support.md @@ -26,6 +26,7 @@ | gettext | | | | | gmp | yes | yes | | | iconv | yes | yes | | +| imagick | | yes | | | inotify | yes | yes | | | mbstring | yes | yes | | | mbregex | yes | yes | | @@ -56,7 +57,7 @@ | xml | yes | yes | | | xmlreader | yes, untested | yes, untested | | | xmlwriter | yes, untested | yes, untested | | -| zip | yes, untested | yes | | +| zip | yes, untested | yes, untested | | | zlib | yes | yes | | | zstd | yes | yes | | diff --git a/src/SPC/builder/BuilderBase.php b/src/SPC/builder/BuilderBase.php index 09240cb0..83097896 100644 --- a/src/SPC/builder/BuilderBase.php +++ b/src/SPC/builder/BuilderBase.php @@ -63,6 +63,9 @@ abstract class BuilderBase if ($libraries === [] && $this->isLibsOnly()) { $libraries = array_keys($support_lib_list); } + if (!in_array('pkg-config', $libraries)) { + array_unshift($libraries, 'pkg-config'); + } // 排序 libs,根据依赖计算一个新的列表出来 $libraries = DependencyUtil::getLibsByDeps($libraries); diff --git a/src/SPC/builder/LibraryBase.php b/src/SPC/builder/LibraryBase.php index dfd6b859..7f234a5b 100644 --- a/src/SPC/builder/LibraryBase.php +++ b/src/SPC/builder/LibraryBase.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace SPC\builder; +use SPC\builder\macos\library\MacOSLibraryBase; use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; use SPC\store\Config; @@ -152,6 +153,11 @@ abstract class LibraryBase return BUILD_STATUS_OK; } } + // pkg-config 做特殊处理,如果是 pkg-config 就检查有没有 pkg-config 二进制 + if ($this instanceof MacOSLibraryBase && static::NAME === 'pkg-config' && !file_exists(BUILD_ROOT_PATH . '/bin/pkg-config')) { + $this->tryBuild(true); + return BUILD_STATUS_OK; + } // 到这里说明所有的文件都存在,就跳过编译 return BUILD_STATUS_ALREADY; } diff --git a/src/SPC/builder/extension/imagick.php b/src/SPC/builder/extension/imagick.php new file mode 100644 index 00000000..ed456e17 --- /dev/null +++ b/src/SPC/builder/extension/imagick.php @@ -0,0 +1,17 @@ +cxx ); // 设置 pkgconfig - $this->pkgconf_env = 'PKG_CONFIG_PATH="' . BUILD_LIB_PATH . '/pkgconfig"'; + $this->pkgconf_env = 'PKG_CONFIG="' . BUILD_ROOT_PATH . '/bin/pkg-config" PKG_CONFIG_PATH="' . BUILD_LIB_PATH . '/pkgconfig"'; // 设置 configure 依赖的环境变量 $this->configure_env = $this->pkgconf_env . ' ' . @@ -141,6 +141,9 @@ class LinuxBuilder extends BuilderBase if ($this->getExt('swoole')) { $extra_libs .= ' -lstdc++'; } + if ($this->getExt('imagick')) { + $extra_libs .= ' /usr/lib/libMagick++-7.Q16HDRI.a /usr/lib/libMagickCore-7.Q16HDRI.a /usr/lib/libMagickWand-7.Q16HDRI.a'; + } $envs = $this->pkgconf_env . ' ' . "CC='{$this->cc}' " . @@ -169,7 +172,7 @@ class LinuxBuilder extends BuilderBase shell()->cd(SOURCE_PATH . '/php-src')->exec('./buildconf --force'); SourcePatcher::patchPHPConfigure($this); - + if ($this->getPHPVersionID() < 80000) { $json_74 = '--enable-json '; } else { diff --git a/src/SPC/builder/linux/SystemUtil.php b/src/SPC/builder/linux/SystemUtil.php index b0a43789..5f2df6a3 100644 --- a/src/SPC/builder/linux/SystemUtil.php +++ b/src/SPC/builder/linux/SystemUtil.php @@ -149,7 +149,7 @@ class SystemUtil { $paths = getenv('LIBPATH'); if (!$paths) { - $paths = '/lib:/lib64:/usr/lib:/usr/lib64:/usr/local/lib:/usr/local/lib64'; + $paths = '/lib:/lib64:/usr/lib:/usr/lib64:/usr/local/lib:/usr/local/lib64:'; } foreach (explode(':', $paths) as $path) { if (file_exists("{$path}/{$name}")) { diff --git a/src/SPC/builder/linux/library/LinuxLibraryBase.php b/src/SPC/builder/linux/library/LinuxLibraryBase.php index 1105578f..2712976b 100644 --- a/src/SPC/builder/linux/library/LinuxLibraryBase.php +++ b/src/SPC/builder/linux/library/LinuxLibraryBase.php @@ -61,6 +61,11 @@ abstract class LinuxLibraryBase extends LibraryBase return BUILD_STATUS_OK; } } + // pkg-config 做特殊处理,如果是 pkg-config 就检查有没有 pkg-config 二进制 + if (static::NAME === 'pkg-config' && !file_exists(BUILD_ROOT_PATH . '/bin/pkg-config')) { + $this->tryBuild(true); + return BUILD_STATUS_OK; + } // 到这里说明所有的文件都存在,就跳过编译 return BUILD_STATUS_ALREADY; } diff --git a/src/SPC/builder/linux/library/libpng.php b/src/SPC/builder/linux/library/libpng.php index 5c28d1e2..e3d0e2ce 100644 --- a/src/SPC/builder/linux/library/libpng.php +++ b/src/SPC/builder/linux/library/libpng.php @@ -61,5 +61,6 @@ class libpng extends LinuxLibraryBase ->cd(BUILD_LIB_PATH) ->exec('ln -sf libpng16.a libpng.a'); $this->patchPkgconfPrefix(['libpng16.pc'], PKGCONF_PATCH_PREFIX); + $this->cleanLaFiles(); } } diff --git a/src/SPC/builder/linux/library/pkgconfig.php b/src/SPC/builder/linux/library/pkgconfig.php new file mode 100644 index 00000000..eacca36d --- /dev/null +++ b/src/SPC/builder/linux/library/pkgconfig.php @@ -0,0 +1,15 @@ +cmake_toolchain_file = SystemUtil::makeCmakeToolchainFile('Darwin', $this->arch, $this->arch_c_flags); // 设置 configure 依赖的环境变量 $this->configure_env = + 'PKG_CONFIG="' . BUILD_ROOT_PATH . '/bin/pkg-config" ' . 'PKG_CONFIG_PATH="' . BUILD_LIB_PATH . '/pkgconfig/" ' . "CC='{$this->cc}' " . "CXX='{$this->cxx}' " . @@ -145,7 +146,7 @@ class MacOSBuilder extends BuilderBase if ($this->getLib('libxml2') || $this->getExt('iconv')) { $extra_libs .= ' -liconv'; } - + if ($this->getPHPVersionID() < 80000) { $json_74 = '--enable-json '; } else { diff --git a/src/SPC/builder/macos/library/imagemagick.php b/src/SPC/builder/macos/library/imagemagick.php new file mode 100644 index 00000000..c6a105c5 --- /dev/null +++ b/src/SPC/builder/macos/library/imagemagick.php @@ -0,0 +1,60 @@ +builder->getLib('libjpeg') ? '--with-jpeg ' : ''; + // png support + $extra .= $this->builder->getLib('libpng') ? '--with-png ' : ''; + // webp support + $extra .= $this->builder->getLib('libwebp') ? '--with-webp ' : ''; + // zstd support + // $extra .= $this->builder->getLib('zstd') ? '--with-zstd ' : '--without-zstd '; + // freetype support + $extra .= $this->builder->getLib('freetype') ? '--with-freetype ' : '--without-freetype '; + + shell()->cd($this->source_dir) + ->exec( + "{$this->builder->configure_env} ./configure " . + '--enable-static --disable-shared ' . + $extra . + '--prefix=' + ) + ->exec('make clean') + ->exec("make -j{$this->builder->concurrency}") + ->exec('make install DESTDIR=' . BUILD_ROOT_PATH); + $filelist = [ + 'ImageMagick.pc', + 'ImageMagick-7.Q16HDRI.pc', + 'Magick++.pc', + 'Magick++-7.Q16HDRI.pc', + 'MagickCore.pc', + 'MagickCore-7.Q16HDRI.pc', + 'MagickWand.pc', + 'MagickWand-7.Q16HDRI.pc', + ]; + $this->patchPkgconfPrefix($filelist); + foreach ($filelist as $file) { + FileSystem::replaceFile( + BUILD_LIB_PATH . '/pkgconfig/' . $file, + REPLACE_FILE_PREG, + '#includearchdir=/include/ImageMagick-7#m', + 'includearchdir=${prefix}/include/ImageMagick-7' + ); + } + } +} diff --git a/src/SPC/builder/macos/library/libpng.php b/src/SPC/builder/macos/library/libpng.php index 07d3c767..76a0645e 100644 --- a/src/SPC/builder/macos/library/libpng.php +++ b/src/SPC/builder/macos/library/libpng.php @@ -55,5 +55,6 @@ class libpng extends MacOSLibraryBase ->cd(BUILD_LIB_PATH) ->exec('ln -sf libpng16.a libpng.a'); $this->patchPkgconfPrefix(['libpng16.pc'], PKGCONF_PATCH_PREFIX); + $this->cleanLaFiles(); } } diff --git a/src/SPC/builder/macos/library/pkgconfig.php b/src/SPC/builder/macos/library/pkgconfig.php new file mode 100644 index 00000000..bb74dfaa --- /dev/null +++ b/src/SPC/builder/macos/library/pkgconfig.php @@ -0,0 +1,15 @@ +getStaticLibs() as $lib) { + $filename = pathinfo($lib, PATHINFO_FILENAME) . '.la'; + if (file_exists(BUILD_LIB_PATH . '/' . $filename)) { + unlink(BUILD_LIB_PATH . '/' . $filename); + } + } + } } diff --git a/src/SPC/builder/traits/UnixSystemUtilTrait.php b/src/SPC/builder/traits/UnixSystemUtilTrait.php index adc25a5f..46a30ca8 100644 --- a/src/SPC/builder/traits/UnixSystemUtilTrait.php +++ b/src/SPC/builder/traits/UnixSystemUtilTrait.php @@ -47,6 +47,7 @@ SET(CMAKE_CXX_FLAGS "{$cflags}") SET(CMAKE_FIND_ROOT_PATH "{$root}") SET(CMAKE_PREFIX_PATH "{$root}") +set(PKG_CONFIG_EXECUTABLE "{$root}/bin/pkg-config") set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) diff --git a/src/SPC/builder/unix/library/freetype.php b/src/SPC/builder/unix/library/freetype.php index 750622c3..18b77997 100644 --- a/src/SPC/builder/unix/library/freetype.php +++ b/src/SPC/builder/unix/library/freetype.php @@ -4,6 +4,8 @@ declare(strict_types=1); namespace SPC\builder\unix\library; +use SPC\store\FileSystem; + trait freetype { protected function build() @@ -25,5 +27,13 @@ trait freetype ->exec("make -j{$this->builder->concurrency}") ->exec('make install DESTDIR=' . BUILD_ROOT_PATH); $this->patchPkgconfPrefix(['freetype2.pc']); + FileSystem::replaceFile( + BUILD_ROOT_PATH . '/lib/pkgconfig/freetype2.pc', + REPLACE_FILE_STR, + ' -L/lib ', + ' -L' . BUILD_ROOT_PATH . '/lib ' + ); + + $this->cleanLaFiles(); } } diff --git a/src/SPC/builder/unix/library/libavif.php b/src/SPC/builder/unix/library/libavif.php index 413b471d..ac27a5d9 100644 --- a/src/SPC/builder/unix/library/libavif.php +++ b/src/SPC/builder/unix/library/libavif.php @@ -24,5 +24,6 @@ trait libavif ->exec('make install DESTDIR=' . BUILD_ROOT_PATH); // patch pkgconfig $this->patchPkgconfPrefix(['libavif.pc']); + $this->cleanLaFiles(); } } diff --git a/src/SPC/builder/unix/library/libjpeg.php b/src/SPC/builder/unix/library/libjpeg.php index 08c51d85..65da0c08 100644 --- a/src/SPC/builder/unix/library/libjpeg.php +++ b/src/SPC/builder/unix/library/libjpeg.php @@ -24,5 +24,6 @@ trait libjpeg ->exec('make install DESTDIR=' . BUILD_ROOT_PATH); // patch pkgconfig $this->patchPkgconfPrefix(['libjpeg.pc', 'libturbojpeg.pc']); + $this->cleanLaFiles(); } } diff --git a/src/SPC/builder/unix/library/libwebp.php b/src/SPC/builder/unix/library/libwebp.php index 9d06842d..f6e7a596 100644 --- a/src/SPC/builder/unix/library/libwebp.php +++ b/src/SPC/builder/unix/library/libwebp.php @@ -28,5 +28,6 @@ trait libwebp ->exec("make -j{$this->builder->concurrency}") ->exec('make install DESTDIR=' . $destdir); $this->patchPkgconfPrefix(['libsharpyuv.pc', 'libwebp.pc', 'libwebpdecoder.pc', 'libwebpdemux.pc', 'libwebpmux.pc'], PKGCONF_PATCH_PREFIX); + $this->cleanLaFiles(); } } diff --git a/src/SPC/builder/unix/library/libzip.php b/src/SPC/builder/unix/library/libzip.php index f50a6144..b4b8f99f 100644 --- a/src/SPC/builder/unix/library/libzip.php +++ b/src/SPC/builder/unix/library/libzip.php @@ -15,8 +15,8 @@ trait libzip $extra .= $this->builder->getLib('bzip2') ? '-DENABLE_BZIP2=ON ' : '-DENABLE_BZIP2=OFF '; // lib:xz $extra .= $this->builder->getLib('xz') ? '-DENABLE_LZMA=ON ' : '-DENABLE_LZMA=OFF '; - // lib:zstd - $extra .= $this->builder->getLib('zstd') ? '-DENABLE_ZSTD=ON ' : '-DENABLE_ZSTD=OFF '; + // lib:zstd (disabled due to imagemagick link issue + $extra .= /* $this->builder->getLib('zstd') ? '-DENABLE_ZSTD=ON ' : */ '-DENABLE_ZSTD=OFF '; // lib:openssl $extra .= $this->builder->getLib('openssl') ? '-DENABLE_OPENSSL=ON ' : '-DENABLE_OPENSSL=OFF '; diff --git a/src/SPC/builder/unix/library/pkgconfig.php b/src/SPC/builder/unix/library/pkgconfig.php new file mode 100644 index 00000000..6cc475d9 --- /dev/null +++ b/src/SPC/builder/unix/library/pkgconfig.php @@ -0,0 +1,43 @@ +builder->cc}' " . + "CXX='{$this->builder->cxx}' " . + "CFLAGS='{$this->builder->arch_c_flags} -Wimplicit-function-declaration' "; + $linux_env = 'PKG_CONFIG_PATH="' . BUILD_LIB_PATH . '/pkgconfig" ' . + "CC='{$this->builder->cc}' " . + "CXX='{$this->builder->cxx}' "; + + $extra = match (PHP_OS_FAMILY) { + 'Darwin' => '', + default => '--with-internal-glib ', + }; + shell()->cd($this->source_dir) + ->exec( + match (PHP_OS_FAMILY) { + 'Darwin' => $macos_env, + default => $linux_env, + } . + './configure ' . + '--disable-shared ' . + '--enable-static ' . + $extra . + '--prefix=' . BUILD_ROOT_PATH . ' ' . + '--without-sysroot ' . + '--without-system-include-path ' . + '--without-system-library-path ' . + '--without-pc-path' + ) + ->exec('make clean') + ->exec("make -j{$this->builder->concurrency}") + ->exec('make install'); + } +} diff --git a/src/SPC/store/SourcePatcher.php b/src/SPC/store/SourcePatcher.php index 9319b220..e8171efb 100644 --- a/src/SPC/store/SourcePatcher.php +++ b/src/SPC/store/SourcePatcher.php @@ -6,6 +6,7 @@ namespace SPC\store; use SPC\builder\BuilderBase; use SPC\builder\linux\LinuxBuilder; +use SPC\builder\linux\SystemUtil; use SPC\builder\macos\MacOSBuilder; use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; @@ -99,6 +100,14 @@ class SourcePatcher '-lz', BUILD_LIB_PATH . '/libz.a' ); + if (SystemUtil::getOSRelease()['dist'] === 'alpine') { + FileSystem::replaceFile( + SOURCE_PATH . '/libpng/configure', + REPLACE_FILE_STR, + '-lm', + '/usr/lib/libm.a' + ); + } } public static function patchCurlMacOS(): void diff --git a/src/globals/functions.php b/src/globals/functions.php index 9ce84214..5f6cc29f 100644 --- a/src/globals/functions.php +++ b/src/globals/functions.php @@ -66,6 +66,8 @@ function osfamily2dir(): string } /** + * 执行shell,直接输出在终端,出现错误抛出异常 + * * @throws \SPC\exception\RuntimeException */ function f_passthru(string $cmd): ?bool @@ -89,7 +91,13 @@ function f_passthru(string $cmd): ?bool return $ret; } -function f_exec(string $command, &$output, &$result_code) +/** + * 执行命令,不输出内容,返回执行结果和内容 + * + * @param mixed $output + * @param mixed $result_code + */ +function f_exec(string $command, &$output, &$result_code): bool|string { logger()->debug('Running command (no output) : ' . $command); return exec($command, $output, $result_code);