diff --git a/src/SPC/builder/Extension.php b/src/SPC/builder/Extension.php index 7e81cb88..24118844 100644 --- a/src/SPC/builder/Extension.php +++ b/src/SPC/builder/Extension.php @@ -136,6 +136,33 @@ class Extension return ''; } + /** + * Patch code before ./buildconf + * If you need to patch some code, overwrite this and return true + */ + public function patchBeforeBuildconf(): bool + { + return false; + } + + /** + * Patch code before ./configure + * If you need to patch some code, overwrite this and return true + */ + public function patchBeforeConfigure(): bool + { + return false; + } + + /** + * Patch code before make + * If you need to patch some code, overwrite this and return true + */ + public function patchBeforeMake(): bool + { + return false; + } + /** * @throws RuntimeException */ diff --git a/src/SPC/builder/LibraryBase.php b/src/SPC/builder/LibraryBase.php index 7f234a5b..5b0828dd 100644 --- a/src/SPC/builder/LibraryBase.php +++ b/src/SPC/builder/LibraryBase.php @@ -135,6 +135,7 @@ abstract class LibraryBase // 传入 true,表明直接编译 if ($force_build) { logger()->info('Building required library [' . static::NAME . ']'); + $this->patchBeforeBuild(); $this->build(); return BUILD_STATUS_OK; } @@ -162,6 +163,14 @@ abstract class LibraryBase return BUILD_STATUS_ALREADY; } + /** + * Patch before build, overwrite this and return true to patch libs + */ + public function patchBeforeBuild(): bool + { + return false; + } + /** * 获取构建当前 lib 的 Builder 对象 */ diff --git a/src/SPC/builder/linux/LinuxBuilder.php b/src/SPC/builder/linux/LinuxBuilder.php index b0237de8..e088b0d6 100644 --- a/src/SPC/builder/linux/LinuxBuilder.php +++ b/src/SPC/builder/linux/LinuxBuilder.php @@ -169,11 +169,11 @@ class LinuxBuilder extends BuilderBase $envs = "{$envs} CFLAGS='{$cflags}' LIBS='-ldl -lpthread'"; - SourcePatcher::patchPHPBuildconf($this); + SourcePatcher::patchBeforeBuildconf($this); shell()->cd(SOURCE_PATH . '/php-src')->exec('./buildconf --force'); - SourcePatcher::patchPHPConfigure($this); + SourcePatcher::patchBeforeConfigure($this); if ($this->getPHPVersionID() < 80000) { $json_74 = '--enable-json '; @@ -200,7 +200,7 @@ class LinuxBuilder extends BuilderBase $envs ); - SourcePatcher::patchPHPAfterConfigure($this); + SourcePatcher::patchBeforeMake($this); file_put_contents('/tmp/comment', $this->note_section); diff --git a/src/SPC/builder/linux/library/LinuxLibraryBase.php b/src/SPC/builder/linux/library/LinuxLibraryBase.php index 2712976b..e3d9878e 100644 --- a/src/SPC/builder/linux/library/LinuxLibraryBase.php +++ b/src/SPC/builder/linux/library/LinuxLibraryBase.php @@ -43,6 +43,7 @@ abstract class LinuxLibraryBase extends LibraryBase // 传入 true,表明直接编译 if ($force_build) { logger()->info('Building required library [' . static::NAME . ']'); + $this->patchBeforeBuild(); $this->build(); return BUILD_STATUS_OK; } diff --git a/src/SPC/builder/macos/MacOSBuilder.php b/src/SPC/builder/macos/MacOSBuilder.php index c41c944f..5e48629e 100644 --- a/src/SPC/builder/macos/MacOSBuilder.php +++ b/src/SPC/builder/macos/MacOSBuilder.php @@ -140,12 +140,12 @@ class MacOSBuilder extends BuilderBase ); } - // patch before configure - SourcePatcher::patchPHPBuildconf($this); + // patch before buildconf + SourcePatcher::patchBeforeBuildconf($this); shell()->cd(SOURCE_PATH . '/php-src')->exec('./buildconf --force'); - SourcePatcher::patchPHPConfigure($this); + SourcePatcher::patchBeforeConfigure($this); if ($this->getLib('libxml2') || $this->getExt('iconv')) { $extra_libs .= ' -liconv'; @@ -177,7 +177,7 @@ class MacOSBuilder extends BuilderBase $this->configure_env ); - SourcePatcher::patchPHPAfterConfigure($this); + SourcePatcher::patchBeforeMake($this); $this->cleanMake(); diff --git a/src/SPC/store/SourcePatcher.php b/src/SPC/store/SourcePatcher.php index 56b3c7b9..ecd3f05d 100644 --- a/src/SPC/store/SourcePatcher.php +++ b/src/SPC/store/SourcePatcher.php @@ -6,164 +6,47 @@ 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; -use SPC\util\Util; class SourcePatcher { public static function init() { - FileSystem::addSourceExtractHook('swow', [SourcePatcher::class, 'patchSwow']); + // FileSystem::addSourceExtractHook('swow', [SourcePatcher::class, 'patchSwow']); FileSystem::addSourceExtractHook('micro', [SourcePatcher::class, 'patchMicro']); FileSystem::addSourceExtractHook('openssl', [SourcePatcher::class, 'patchOpenssl11Darwin']); } - public static function patchPHPBuildconf(BuilderBase $builder): void + /** + * Source patcher runner before buildconf + * + * @param BuilderBase $builder Builder + */ + public static function patchBeforeBuildconf(BuilderBase $builder): void { - if ($builder->getExt('curl')) { - logger()->info('patching before-configure for curl checks'); - $file1 = "AC_DEFUN([PHP_CHECK_LIBRARY], [\n $3\n])"; - $files = FileSystem::readFile(SOURCE_PATH . '/php-src/ext/curl/config.m4'); - $file2 = 'AC_DEFUN([PHP_CHECK_LIBRARY], [ - save_old_LDFLAGS=$LDFLAGS - ac_stuff="$5" - - save_ext_shared=$ext_shared - ext_shared=yes - PHP_EVAL_LIBLINE([$]ac_stuff, LDFLAGS) - AC_CHECK_LIB([$1],[$2],[ - LDFLAGS=$save_old_LDFLAGS - ext_shared=$save_ext_shared - $3 - ],[ - LDFLAGS=$save_old_LDFLAGS - ext_shared=$save_ext_shared - unset ac_cv_lib_$1[]_$2 - $4 - ])dnl -])'; - file_put_contents(SOURCE_PATH . '/php-src/ext/curl/config.m4', $file1 . "\n" . $files . "\n" . $file2); - } - - if ($builder->getExt('memcache')) { - FileSystem::replaceFile( - SOURCE_PATH . '/php-src/ext/memcache/config9.m4', - REPLACE_FILE_STR, - 'if test -d $abs_srcdir/src ; then', - 'if test -d $abs_srcdir/main ; then' - ); - FileSystem::replaceFile( - SOURCE_PATH . '/php-src/ext/memcache/config9.m4', - REPLACE_FILE_STR, - 'export CPPFLAGS="$CPPFLAGS $INCLUDES"', - 'export CPPFLAGS="$CPPFLAGS $INCLUDES -I$abs_srcdir/main"' - ); - // add for in-tree building - file_put_contents( - SOURCE_PATH . '/php-src/ext/memcache/php_memcache.h', - <<<'EOF' -#ifndef PHP_MEMCACHE_H -#define PHP_MEMCACHE_H - -extern zend_module_entry memcache_module_entry; -#define phpext_memcache_ptr &memcache_module_entry - -#endif -EOF - ); - } - } - - public static function patchSwow(): bool - { - if (Util::getPHPVersionID() >= 80000) { - if (PHP_OS_FAMILY === 'Windows') { - f_passthru('cd ' . SOURCE_PATH . '/php-src/ext && mklink /D swow swow-src\ext'); - } else { - f_passthru('cd ' . SOURCE_PATH . '/php-src/ext && ln -s swow-src/ext swow'); + foreach ($builder->getExts() as $ext) { + if ($ext->patchBeforeBuildconf() === true) { + logger()->info('Extension [' . $ext->getName() . '] patched before buildconf'); } - return true; - } - return false; - } - - public static function patchPHPConfigure(BuilderBase $builder): void - { - $frameworks = $builder instanceof MacOSBuilder ? ' ' . $builder->getFrameworks(true) . ' ' : ''; - $patch = []; - if ($curl = $builder->getExt('curl')) { - $patch[] = ['curl check', '/-lcurl/', $curl->getLibFilesString() . $frameworks]; - } - if ($bzip2 = $builder->getExt('bz2')) { - $patch[] = ['bzip2 check', '/-lbz2/', $bzip2->getLibFilesString() . $frameworks]; - } - if ($pdo_sqlite = $builder->getExt('pdo_sqlite')) { - $patch[] = ['pdo_sqlite linking', '/sqlite3_column_table_name=yes/', 'sqlite3_column_table_name=no']; - } - if ($event = $builder->getExt('event')) { - $patch[] = ['event check', '/-levent_openssl/', $event->getLibFilesString()]; - } - if ($readline = $builder->getExt('readline')) { - $patch[] = ['readline patch', '/-lncurses/', $readline->getLibFilesString()]; - } - if ($ssh2 = $builder->getExt('ssh2')) { - $patch[] = ['ssh2 patch', '/-lssh2/', $ssh2->getLibFilesString()]; - } - if ($pgsql = $builder->getExt('pgsql')) { - $patch[] = ['pgsql patch', '/-lpq/', $pgsql->getLibFilesString()]; - } - $patch[] = ['disable capstone', '/have_capstone="yes"/', 'have_capstone="no"']; - foreach ($patch as $item) { - logger()->info('Patching configure: ' . $item[0]); - FileSystem::replaceFile(SOURCE_PATH . '/php-src/configure', REPLACE_FILE_PREG, $item[1], $item[2]); } } - public static function patchUnixLibpng(): void + /** + * Source patcher runner before configure + * + * @param BuilderBase $builder Builder + * @throws FileSystemException + */ + public static function patchBeforeConfigure(BuilderBase $builder): void { - FileSystem::replaceFile( - SOURCE_PATH . '/libpng/configure', - REPLACE_FILE_STR, - '-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' - ); + foreach ($builder->getExts() as $ext) { + if ($ext->patchBeforeConfigure() === true) { + logger()->info('Extension [' . $ext->getName() . '] patched before configure'); + } } - } - - public static function patchUnixSsh2(): void - { - FileSystem::replaceFile( - SOURCE_PATH . '/php-src/configure', - REPLACE_FILE_STR, - '-lssh2', - BUILD_LIB_PATH . '/libssh2.a' - ); - } - - public static function patchCurlMacOS(): void - { - FileSystem::replaceFile( - SOURCE_PATH . '/curl/CMakeLists.txt', - REPLACE_FILE_PREG, - '/NOT COREFOUNDATION_FRAMEWORK/m', - 'FALSE' - ); - FileSystem::replaceFile( - SOURCE_PATH . '/curl/CMakeLists.txt', - REPLACE_FILE_PREG, - '/NOT SYSTEMCONFIGURATION_FRAMEWORK/m', - 'FALSE' - ); + // patch capstone + FileSystem::replaceFile(SOURCE_PATH . '/php-src/configure', REPLACE_FILE_PREG, '/have_capstone="yes"/', 'have_capstone="no"'); } public static function patchMicro(?array $list = null, bool $reverse = false): bool @@ -244,19 +127,23 @@ EOF return false; } - public static function patchPHPAfterConfigure(BuilderBase $param) + /** + * @throws FileSystemException + */ + public static function patchBeforeMake(BuilderBase $builder): void { - if ($param instanceof LinuxBuilder) { + // Try to fix debian environment build lack HAVE_STRLCAT problem + if ($builder instanceof LinuxBuilder) { FileSystem::replaceFile(SOURCE_PATH . '/php-src/main/php_config.h', REPLACE_FILE_PREG, '/^#define HAVE_STRLCPY 1$/m', ''); FileSystem::replaceFile(SOURCE_PATH . '/php-src/main/php_config.h', REPLACE_FILE_PREG, '/^#define HAVE_STRLCAT 1$/m', ''); } FileSystem::replaceFile(SOURCE_PATH . '/php-src/main/php_config.h', REPLACE_FILE_PREG, '/^#define HAVE_OPENPTY 1$/m', ''); - // patch openssl3 with php8.0 bug - if (file_exists(SOURCE_PATH . '/openssl/VERSION.dat') && Util::getPHPVersionID() < 80100) { - $openssl_c = file_get_contents(SOURCE_PATH . '/php-src/ext/openssl/openssl.c'); - $openssl_c = preg_replace('/REGISTER_LONG_CONSTANT\s*\(\s*"OPENSSL_SSLV23_PADDING"\s*.+;/', '', $openssl_c); - file_put_contents(SOURCE_PATH . '/php-src/ext/openssl/openssl.c', $openssl_c); + // call extension patch before make + foreach ($builder->getExts() as $ext) { + if ($ext->patchBeforeMake() === true) { + logger()->info('Extension [' . $ext->getName() . '] patched before make'); + } } } }