diff --git a/.gitignore b/.gitignore index 5fef8d36..a95eeaac 100644 --- a/.gitignore +++ b/.gitignore @@ -5,25 +5,25 @@ docker/extensions/ docker/source/ # Vendor files -/vendor/ +/vendor/** # default source extract directory -/source/ +/source/** # built by shared embed tests /locale/ # default source download directory -/downloads/ +/downloads/** # default source build root directory -/buildroot/ +/buildroot/** # default package root directory -/pkgroot/ +/pkgroot/** # default pack:lib and release directory -/dist/ +/dist/** packlib_files.txt # tools cache files diff --git a/src/SPC/builder/Extension.php b/src/SPC/builder/Extension.php index d0df37b5..c11644dd 100644 --- a/src/SPC/builder/Extension.php +++ b/src/SPC/builder/Extension.php @@ -366,7 +366,7 @@ class Extension // prepare configure args shell()->cd($this->source_dir) ->setEnv($env) - ->execWithEnv(BUILD_BIN_PATH . '/phpize'); + ->exec(BUILD_BIN_PATH . '/phpize'); if ($this->patchBeforeSharedConfigure()) { logger()->info('ext [ . ' . $this->getName() . '] patching before shared configure'); @@ -374,10 +374,10 @@ class Extension shell()->cd($this->source_dir) ->setEnv($env) - ->execWithEnv('./configure ' . $this->getUnixConfigureArg(true) . ' --with-php-config=' . BUILD_BIN_PATH . '/php-config --with-pic') - ->execWithEnv('make clean') - ->execWithEnv('make -j' . $this->builder->concurrency) - ->execWithEnv('make install'); + ->exec('./configure ' . $this->getUnixConfigureArg(true) . ' --with-php-config=' . BUILD_BIN_PATH . '/php-config --enable-shared --disable-static') + ->exec('make clean') + ->exec('make -j' . $this->builder->concurrency) + ->exec('make install'); } /** diff --git a/src/SPC/builder/LibraryBase.php b/src/SPC/builder/LibraryBase.php index abf9dd50..0d8ab739 100644 --- a/src/SPC/builder/LibraryBase.php +++ b/src/SPC/builder/LibraryBase.php @@ -328,6 +328,21 @@ abstract class LibraryBase return false; } + public function getIncludeDir(): string + { + return BUILD_INCLUDE_PATH; + } + + public function getBuildRootPath(): string + { + return BUILD_ROOT_PATH; + } + + public function getLibDir(): string + { + return BUILD_LIB_PATH; + } + /** * Build this library. * diff --git a/src/SPC/builder/freebsd/BSDBuilder.php b/src/SPC/builder/freebsd/BSDBuilder.php index 7c10881f..04fd43d3 100644 --- a/src/SPC/builder/freebsd/BSDBuilder.php +++ b/src/SPC/builder/freebsd/BSDBuilder.php @@ -47,8 +47,6 @@ class BSDBuilder extends UnixBuilderBase // cflags $this->arch_c_flags = SystemUtil::getArchCFlags($this->getOption('arch')); $this->arch_cxx_flags = SystemUtil::getArchCFlags($this->getOption('arch')); - // cmake toolchain - $this->cmake_toolchain_file = SystemUtil::makeCmakeToolchainFile('BSD', $this->getOption('arch'), $this->arch_c_flags); // create pkgconfig and include dir (some libs cannot create them automatically) f_mkdir(BUILD_LIB_PATH . '/pkgconfig', recursive: true); diff --git a/src/SPC/builder/linux/LinuxBuilder.php b/src/SPC/builder/linux/LinuxBuilder.php index 850f7b01..00732619 100644 --- a/src/SPC/builder/linux/LinuxBuilder.php +++ b/src/SPC/builder/linux/LinuxBuilder.php @@ -48,14 +48,6 @@ class LinuxBuilder extends UnixBuilderBase // cflags $this->arch_c_flags = getenv('SPC_DEFAULT_C_FLAGS'); $this->arch_cxx_flags = getenv('SPC_DEFAULT_CXX_FLAGS'); - // cmake toolchain - $this->cmake_toolchain_file = SystemUtil::makeCmakeToolchainFile( - 'Linux', - $arch, - $this->arch_c_flags, - getenv('CC'), - getenv('CXX'), - ); // cross-compiling is not supported yet /*if (php_uname('m') !== $this->arch) { diff --git a/src/SPC/builder/linux/library/libffi.php b/src/SPC/builder/linux/library/libffi.php index aa4cd662..fa221bd1 100644 --- a/src/SPC/builder/linux/library/libffi.php +++ b/src/SPC/builder/linux/library/libffi.php @@ -21,12 +21,8 @@ class libffi extends LinuxLibraryBase $arch = getenv('SPC_ARCH'); shell()->cd($this->source_dir) - ->setEnv([ - 'CFLAGS' => $this->getLibExtraCFlags(), - 'LDFLAGS' => $this->getLibExtraLdFlags(), - 'LIBS' => $this->getLibExtraLibs(), - ]) - ->execWithEnv( + ->initializeEnv($this) + ->exec( './configure ' . '--enable-static ' . '--disable-shared ' . @@ -36,9 +32,9 @@ class libffi extends LinuxLibraryBase '--prefix= ' . "--libdir={$lib}" ) - ->execWithEnv('make clean') - ->execWithEnv("make -j{$this->builder->concurrency}") - ->execWithEnv("make install DESTDIR={$destdir}"); + ->exec('make clean') + ->exec("make -j{$this->builder->concurrency}") + ->exec("make install DESTDIR={$destdir}"); if (is_file(BUILD_ROOT_PATH . '/lib64/libffi.a')) { copy(BUILD_ROOT_PATH . '/lib64/libffi.a', BUILD_ROOT_PATH . '/lib/libffi.a'); diff --git a/src/SPC/builder/linux/library/libpng.php b/src/SPC/builder/linux/library/libpng.php index 6bc4df2b..4e911c54 100644 --- a/src/SPC/builder/linux/library/libpng.php +++ b/src/SPC/builder/linux/library/libpng.php @@ -41,15 +41,11 @@ class libpng extends LinuxLibraryBase 'aarch64' => '--enable-arm-neon ', default => '', }; - shell()->cd($this->source_dir) + shell()->cd($this->source_dir)->initializeEnv($this) ->exec('chmod +x ./configure') ->exec('chmod +x ./install-sh') - ->setEnv([ - 'CFLAGS' => $this->getLibExtraCFlags(), - 'LDFLAGS' => $this->getLibExtraLdFlags() . ' -L' . BUILD_LIB_PATH, - 'LIBS' => $this->getLibExtraLibs(), - ]) - ->execWithEnv( + ->exec( + 'LDFLAGS="-L' . BUILD_LIB_PATH . '" ' . './configure ' . '--disable-shared ' . '--enable-static ' . diff --git a/src/SPC/builder/linux/library/libxml2.php b/src/SPC/builder/linux/library/libxml2.php index 5f4f1dc9..102f60b7 100644 --- a/src/SPC/builder/linux/library/libxml2.php +++ b/src/SPC/builder/linux/library/libxml2.php @@ -4,50 +4,9 @@ declare(strict_types=1); namespace SPC\builder\linux\library; -use SPC\exception\FileSystemException; -use SPC\exception\RuntimeException; -use SPC\store\FileSystem; - class libxml2 extends LinuxLibraryBase { + use \SPC\builder\unix\library\libxml2; + public const NAME = 'libxml2'; - - /** - * @throws RuntimeException - * @throws FileSystemException - */ - public function build(): void - { - $enable_zlib = $this->builder->getLib('zlib') ? ('ON -DZLIB_LIBRARY=' . BUILD_LIB_PATH . '/libz.a -DZLIB_INCLUDE_DIR=' . BUILD_INCLUDE_PATH) : 'OFF'; - $enable_icu = $this->builder->getLib('icu') ? 'ON' : 'OFF'; - $enable_xz = $this->builder->getLib('xz') ? 'ON' : 'OFF'; - - FileSystem::resetDir($this->source_dir . '/build'); - shell()->cd($this->source_dir . '/build') - ->setEnv([ - 'CFLAGS' => $this->getLibExtraCFlags(), - 'LDFLAGS' => $this->getLibExtraLdFlags(), - 'LIBS' => $this->getLibExtraLibs(), - ]) - ->execWithEnv( - "cmake {$this->builder->makeCmakeArgs()} " . - '-DIconv_IS_BUILT_IN=OFF ' . - '-DLIBXML2_WITH_ICONV=ON ' . - "-DLIBXML2_WITH_ZLIB={$enable_zlib} " . - "-DLIBXML2_WITH_ICU={$enable_icu} " . - "-DLIBXML2_WITH_LZMA={$enable_xz} " . - '-DLIBXML2_WITH_PYTHON=OFF ' . - '-DLIBXML2_WITH_PROGRAMS=OFF ' . - '-DLIBXML2_WITH_TESTS=OFF ' . - '..' - ) - ->execWithEnv("cmake --build . -j {$this->builder->concurrency}") - ->execWithEnv('make install'); - - FileSystem::replaceFileStr( - BUILD_LIB_PATH . '/pkgconfig/libxml-2.0.pc', - '-licudata -licui18n -licuuc', - '-licui18n -licuuc -licudata' - ); - } } diff --git a/src/SPC/builder/linux/library/openssl.php b/src/SPC/builder/linux/library/openssl.php index add81151..11c60067 100644 --- a/src/SPC/builder/linux/library/openssl.php +++ b/src/SPC/builder/linux/library/openssl.php @@ -64,13 +64,8 @@ class openssl extends LinuxLibraryBase $clang_postfix = SystemUtil::getCCType(getenv('CC')) === 'clang' ? '-clang' : ''; - shell()->cd($this->source_dir) - ->setEnv([ - 'CFLAGS' => $this->getLibExtraCFlags(), - 'LDFLAGS' => $this->getLibExtraLdFlags(), - 'LIBS' => $this->getLibExtraLibs(), - ]) - ->execWithEnv( + shell()->cd($this->source_dir)->initializeEnv($this) + ->exec( "{$env} ./Configure no-shared {$extra} " . '--prefix=/ ' . '--libdir=lib ' . @@ -80,7 +75,7 @@ class openssl extends LinuxLibraryBase "linux-{$arch}{$clang_postfix}" ) ->exec('make clean') - ->execWithEnv("make -j{$this->builder->concurrency} CNF_EX_LIBS=\"{$ex_lib}\"") + ->exec("make -j{$this->builder->concurrency} CNF_EX_LIBS=\"{$ex_lib}\"") ->exec("make install_sw DESTDIR={$destdir}"); $this->patchPkgconfPrefix(['libssl.pc', 'openssl.pc', 'libcrypto.pc']); // patch for openssl 3.3.0+ diff --git a/src/SPC/builder/macos/MacOSBuilder.php b/src/SPC/builder/macos/MacOSBuilder.php index e2b1d351..1d4a2949 100644 --- a/src/SPC/builder/macos/MacOSBuilder.php +++ b/src/SPC/builder/macos/MacOSBuilder.php @@ -36,8 +36,6 @@ class MacOSBuilder extends UnixBuilderBase // cflags $this->arch_c_flags = getenv('SPC_DEFAULT_C_FLAGS'); $this->arch_cxx_flags = getenv('SPC_DEFAULT_CXX_FLAGS'); - // cmake toolchain - $this->cmake_toolchain_file = SystemUtil::makeCmakeToolchainFile('Darwin', getenv('SPC_ARCH'), $this->arch_c_flags); // create pkgconfig and include dir (some libs cannot create them automatically) f_mkdir(BUILD_LIB_PATH . '/pkgconfig', recursive: true); diff --git a/src/SPC/builder/macos/library/glfw.php b/src/SPC/builder/macos/library/glfw.php index 8ab84770..8bc7ca18 100644 --- a/src/SPC/builder/macos/library/glfw.php +++ b/src/SPC/builder/macos/library/glfw.php @@ -6,6 +6,7 @@ namespace SPC\builder\macos\library; use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; +use SPC\util\executor\UnixCMakeExecutor; class glfw extends MacOSLibraryBase { @@ -17,11 +18,14 @@ class glfw extends MacOSLibraryBase */ protected function build(): void { - // compile! - shell()->cd(SOURCE_PATH . '/ext-glfw/vendor/glfw') - ->exec("cmake . {$this->builder->makeCmakeArgs()} -DGLFW_BUILD_EXAMPLES=OFF -DGLFW_BUILD_TESTS=OFF") - ->exec("make -j{$this->builder->concurrency}") - ->exec('make install'); + UnixCMakeExecutor::create($this) + ->setBuildDir("{$this->source_dir}/vendor/glfw") + ->setReset(false) + ->addConfigureArgs( + '-DGLFW_BUILD_EXAMPLES=OFF', + '-DGLFW_BUILD_TESTS=OFF', + ) + ->build('.'); // patch pkgconf $this->patchPkgconfPrefix(['glfw3.pc']); } diff --git a/src/SPC/builder/macos/library/libxml2.php b/src/SPC/builder/macos/library/libxml2.php index d4646dba..51fd031e 100644 --- a/src/SPC/builder/macos/library/libxml2.php +++ b/src/SPC/builder/macos/library/libxml2.php @@ -4,39 +4,9 @@ declare(strict_types=1); namespace SPC\builder\macos\library; -use SPC\exception\FileSystemException; -use SPC\exception\RuntimeException; -use SPC\store\FileSystem; - class libxml2 extends MacOSLibraryBase { + use \SPC\builder\unix\library\libxml2; + public const NAME = 'libxml2'; - - /** - * @throws RuntimeException - * @throws FileSystemException - */ - protected function build(): void - { - $enable_zlib = $this->builder->getLib('zlib') ? ('ON -DZLIB_LIBRARY=' . BUILD_LIB_PATH . '/libz.a -DZLIB_INCLUDE_DIR=' . BUILD_INCLUDE_PATH) : 'OFF'; - $enable_icu = $this->builder->getLib('icu') ? 'ON' : 'OFF'; - $enable_xz = $this->builder->getLib('xz') ? 'ON' : 'OFF'; - - FileSystem::resetDir($this->source_dir . '/build'); - shell()->cd($this->source_dir . '/build') - ->exec( - "cmake {$this->builder->makeCmakeArgs()} " . - // '--debug-find ' . - '-DLIBXML2_WITH_ICONV=ON ' . - "-DLIBXML2_WITH_ZLIB={$enable_zlib} " . - "-DLIBXML2_WITH_ICU={$enable_icu} " . - "-DLIBXML2_WITH_LZMA={$enable_xz} " . - '-DLIBXML2_WITH_PYTHON=OFF ' . - '-DLIBXML2_WITH_PROGRAMS=OFF ' . - '-DLIBXML2_WITH_TESTS=OFF ' . - '..' - ) - ->exec("cmake --build . -j {$this->builder->concurrency}") - ->exec('make install'); - } } diff --git a/src/SPC/builder/macos/library/openssl.php b/src/SPC/builder/macos/library/openssl.php index 28796d7c..d641fc1d 100644 --- a/src/SPC/builder/macos/library/openssl.php +++ b/src/SPC/builder/macos/library/openssl.php @@ -49,12 +49,7 @@ class openssl extends MacOSLibraryBase } $arch = getenv('SPC_ARCH'); - shell()->cd($this->source_dir) - ->setEnv([ - 'CFLAGS' => $this->getLibExtraCFlags(), - 'LDFLAGS' => $this->getLibExtraLdFlags(), - 'LIBS' => $this->getLibExtraLibs(), - ]) + shell()->cd($this->source_dir)->initializeEnv($this) ->exec( "./Configure no-shared {$extra} " . '--prefix=/ ' . // use prefix=/ @@ -63,7 +58,7 @@ class openssl extends MacOSLibraryBase "darwin64-{$arch}-cc" ) ->exec('make clean') - ->execWithEnv("make -j{$this->builder->concurrency} CNF_EX_LIBS=\"{$ex_lib}\"") + ->exec("make -j{$this->builder->concurrency} CNF_EX_LIBS=\"{$ex_lib}\"") ->exec("make install_sw DESTDIR={$destdir}"); $this->patchPkgconfPrefix(['libssl.pc', 'openssl.pc', 'libcrypto.pc']); // patch for openssl 3.3.0+ diff --git a/src/SPC/builder/traits/UnixLibraryTrait.php b/src/SPC/builder/traits/UnixLibraryTrait.php index 74d8fd37..fbca595f 100644 --- a/src/SPC/builder/traits/UnixLibraryTrait.php +++ b/src/SPC/builder/traits/UnixLibraryTrait.php @@ -139,4 +139,13 @@ trait UnixLibraryTrait { return getenv($this->getSnakeCaseName() . '_LIBS') ?: ''; } + + public function getLibExtraCXXFlags(): string + { + $env = getenv($this->getSnakeCaseName() . '_CXXFLAGS') ?: ''; + if (!str_contains($env, $this->builder->arch_cxx_flags)) { + $env .= $this->builder->arch_cxx_flags; + } + return $env; + } } diff --git a/src/SPC/builder/traits/UnixSystemUtilTrait.php b/src/SPC/builder/traits/UnixSystemUtilTrait.php index 8b8cb743..3407a00b 100644 --- a/src/SPC/builder/traits/UnixSystemUtilTrait.php +++ b/src/SPC/builder/traits/UnixSystemUtilTrait.php @@ -4,66 +4,11 @@ declare(strict_types=1); namespace SPC\builder\traits; -use SPC\exception\FileSystemException; -use SPC\store\FileSystem; - /** * Unix 系统的工具函数 Trait,适用于 Linux、macOS */ trait UnixSystemUtilTrait { - /** - * 生成 toolchain.cmake,用于 cmake 构建 - * - * @param string $os 操作系统代号 - * @param string $target_arch 目标架构 - * @param string $cflags CFLAGS 参数 - * @param null|string $cc CC 参数(默认空) - * @param null|string $cxx CXX 参数(默认空) - * @throws FileSystemException - */ - public static function makeCmakeToolchainFile( - string $os, - string $target_arch, - string $cflags, - ?string $cc = null, - ?string $cxx = null - ): string { - logger()->debug("making cmake tool chain file for {$os} {$target_arch} with CFLAGS='{$cflags}'"); - $root = BUILD_ROOT_PATH; - $ccLine = ''; - if ($cc) { - $ccLine = 'SET(CMAKE_C_COMPILER ' . $cc . ')'; - } - $cxxLine = ''; - if ($cxx) { - $cxxLine = 'SET(CMAKE_CXX_COMPILER ' . $cxx . ')'; - } - $toolchain = << realpath(BUILD_LIB_PATH . "/{$x}"), $libFiles); } - /** - * Return generic cmake options when configuring cmake projects - */ - public function makeCmakeArgs(): string - { - $extra = $this instanceof LinuxBuilder ? '-DCMAKE_C_COMPILER=' . getenv('CC') . ' ' : ''; - return $extra . - '-DBUILD_STATIC_LIBS=ON ' . - '-DBUILD_SHARED_LIBS=OFF ' . - '-DPOSITION_INDEPENDENT_CODE=ON ' . - '-DCMAKE_BUILD_TYPE=Release ' . - '-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' ' . - '-DCMAKE_INSTALL_BINDIR=bin ' . - '-DCMAKE_INSTALL_LIBDIR=lib ' . - '-DCMAKE_INSTALL_INCLUDEDIR=include ' . - "-DCMAKE_TOOLCHAIN_FILE={$this->cmake_toolchain_file}"; - } - /** * Generate configure flags */ diff --git a/src/SPC/builder/unix/library/attr.php b/src/SPC/builder/unix/library/attr.php index ce542ddd..b6254720 100644 --- a/src/SPC/builder/unix/library/attr.php +++ b/src/SPC/builder/unix/library/attr.php @@ -13,16 +13,12 @@ trait attr */ protected function build(): void { - shell()->cd($this->source_dir) - ->setEnv([ - 'CFLAGS' => trim('-I' . BUILD_INCLUDE_PATH . ' ' . $this->getLibExtraCFlags()), - 'LDFLAGS' => trim('-L' . BUILD_LIB_PATH . ' ' . $this->getLibExtraLdFlags()), - 'LIBS' => $this->getLibExtraLibs(), - ]) - ->execWithEnv('libtoolize --force --copy') - ->execWithEnv('./autogen.sh || autoreconf -if') - ->execWithEnv('./configure --prefix= --enable-static --disable-shared --with-pic --disable-nls') - ->execWithEnv("make -j {$this->builder->concurrency}") + shell()->cd($this->source_dir)->initializeEnv($this) + ->appendEnv(['CFLAGS' => "-I{$this->getIncludeDir()}", 'LDFLAGS' => "-L{$this->getLibDir()}"]) + ->exec('libtoolize --force --copy') + ->exec('./autogen.sh || autoreconf -if') + ->exec('./configure --prefix= --enable-static --disable-shared --with-pic --disable-nls') + ->exec("make -j {$this->builder->concurrency}") ->exec('make install DESTDIR=' . BUILD_ROOT_PATH); $this->patchPkgconfPrefix(['libattr.pc'], PKGCONF_PATCH_PREFIX); diff --git a/src/SPC/builder/unix/library/brotli.php b/src/SPC/builder/unix/library/brotli.php index 526f3341..588d27bb 100644 --- a/src/SPC/builder/unix/library/brotli.php +++ b/src/SPC/builder/unix/library/brotli.php @@ -7,6 +7,7 @@ namespace SPC\builder\unix\library; use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; use SPC\store\FileSystem; +use SPC\util\executor\UnixCMakeExecutor; trait brotli { @@ -16,26 +17,11 @@ trait brotli */ protected function build(): void { - FileSystem::resetDir($this->source_dir . '/build-dir'); - shell()->cd($this->source_dir . '/build-dir') - ->setEnv([ - 'CFLAGS' => $this->getLibExtraCFlags(), - 'LDFLAGS' => $this->getLibExtraLdFlags(), - 'LIBS' => $this->getLibExtraLibs(), - ]) - ->execWithEnv( - 'cmake ' . - '-DCMAKE_BUILD_TYPE=Release ' . - "-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " . - '-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' ' . - '-DCMAKE_INSTALL_LIBDIR=lib ' . - '-DSHARE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' ' . - '-DPOSITION_INDEPENDENT_CODE=ON ' . - '-DBUILD_SHARED_LIBS=OFF ' . - '..' - ) - ->execWithEnv("cmake --build . -j {$this->builder->concurrency}") - ->execWithEnv('make install'); + UnixCMakeExecutor::create($this) + ->setBuildDir("{$this->getSourceDir()}/build-dir") + ->addConfigureArgs("-DSHARE_INSTALL_PREFIX={$this->getBuildRootPath()}") + ->build(); + $this->patchPkgconfPrefix(['libbrotlicommon.pc', 'libbrotlidec.pc', 'libbrotlienc.pc']); FileSystem::replaceFileLineContainsString(BUILD_LIB_PATH . '/pkgconfig/libbrotlidec.pc', 'Libs: -L${libdir} -lbrotlidec', 'Libs: -L${libdir} -lbrotlidec -lbrotlicommon'); FileSystem::replaceFileLineContainsString(BUILD_LIB_PATH . '/pkgconfig/libbrotlienc.pc', 'Libs: -L${libdir} -lbrotlienc', 'Libs: -L${libdir} -lbrotlidec -lbrotlicommon'); diff --git a/src/SPC/builder/unix/library/bzip2.php b/src/SPC/builder/unix/library/bzip2.php index 284783c9..32d87270 100644 --- a/src/SPC/builder/unix/library/bzip2.php +++ b/src/SPC/builder/unix/library/bzip2.php @@ -16,14 +16,9 @@ trait bzip2 protected function build(): void { - shell()->cd($this->source_dir) - ->setEnv([ - 'CFLAGS' => $this->getLibExtraCFlags(), - 'LDFLAGS' => $this->getLibExtraLdFlags(), - 'LIBS' => $this->getLibExtraLibs(), - ]) - ->execWithEnv("make PREFIX='" . BUILD_ROOT_PATH . "' clean") - ->execWithEnv("make -j{$this->builder->concurrency} {$this->builder->getEnvString()} PREFIX='" . BUILD_ROOT_PATH . "' libbz2.a") + shell()->cd($this->source_dir)->initializeEnv($this) + ->exec("make PREFIX='" . BUILD_ROOT_PATH . "' clean") + ->exec("make -j{$this->builder->concurrency} {$this->builder->getEnvString()} PREFIX='" . BUILD_ROOT_PATH . "' libbz2.a") ->exec('cp libbz2.a ' . BUILD_LIB_PATH) ->exec('cp bzlib.h ' . BUILD_INCLUDE_PATH); } diff --git a/src/SPC/builder/unix/library/curl.php b/src/SPC/builder/unix/library/curl.php index 7a166b20..c903170d 100644 --- a/src/SPC/builder/unix/library/curl.php +++ b/src/SPC/builder/unix/library/curl.php @@ -6,7 +6,7 @@ namespace SPC\builder\unix\library; use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; -use SPC\store\FileSystem; +use SPC\util\executor\UnixCMakeExecutor; trait curl { @@ -16,79 +16,25 @@ trait curl */ protected function build(): void { - $extra = ''; - // lib:openssl - if ($this->builder->getLib('openssl')) { - $extra .= - '-DCURL_USE_OPENSSL=ON ' . - '-DCURL_CA_BUNDLE=OFF ' . - '-DCURL_CA_PATH=OFF ' . - '-DCURL_CA_FALLBACK=ON '; - } else { - $extra .= '-DCURL_USE_OPENSSL=OFF -DCURL_ENABLE_SSL=OFF '; - } - // lib:brotli - $extra .= $this->builder->getLib('brotli') ? '-DCURL_BROTLI=ON ' : '-DCURL_BROTLI=OFF '; - // lib:libssh2 - $libssh2 = $this->builder->getLib('libssh2'); - if ($this->builder->getLib('libssh2')) { - /* @phpstan-ignore-next-line */ - $extra .= '-DLIBSSH2_LIBRARY="' . $libssh2->getStaticLibFiles(style: 'cmake') . '" ' . - '-DLIBSSH2_INCLUDE_DIR="' . BUILD_INCLUDE_PATH . '" '; - } else { - $extra .= '-DCURL_USE_LIBSSH2=OFF '; - } - // lib:nghttp2 - if ($nghttp2 = $this->builder->getLib('nghttp2')) { - $extra .= '-DUSE_NGHTTP2=ON ' . - /* @phpstan-ignore-next-line */ - '-DNGHTTP2_LIBRARY="' . $nghttp2->getStaticLibFiles(style: 'cmake') . '" ' . - '-DNGHTTP2_INCLUDE_DIR="' . BUILD_INCLUDE_PATH . '" '; - } else { - $extra .= '-DUSE_NGHTTP2=OFF '; - } - // lib:nghttp3 - if ($nghttp3 = $this->builder->getLib('nghttp3')) { - $extra .= '-DUSE_NGHTTP3=ON ' . - /* @phpstan-ignore-next-line */ - '-DNGHTTP3_LIBRARY="' . $nghttp3->getStaticLibFiles(style: 'cmake') . '" ' . - '-DNGHTTP3_INCLUDE_DIR="' . BUILD_INCLUDE_PATH . '" '; - } else { - $extra .= '-DUSE_NGHTTP3=OFF '; - } - // lib:ngtcp2 - if ($ngtcp2 = $this->builder->getLib('ngtcp2')) { - $extra .= '-DUSE_NGTCP2=ON ' . - /* @phpstan-ignore-next-line */ - '-DNGTCP2_LIBRARY="' . $ngtcp2->getStaticLibFiles(style: 'cmake') . '" ' . - '-DNGTCP2_INCLUDE_DIR="' . BUILD_INCLUDE_PATH . '" '; - } else { - $extra .= '-DUSE_NGTCP2=OFF '; - } - // lib:ldap - $extra .= $this->builder->getLib('ldap') ? '-DCURL_DISABLE_LDAP=OFF ' : '-DCURL_DISABLE_LDAP=ON '; - // lib:zstd - $extra .= $this->builder->getLib('zstd') ? '-DCURL_ZSTD=ON ' : '-DCURL_ZSTD=OFF '; - // lib:idn2 - $extra .= $this->builder->getLib('idn2') ? '-DUSE_LIBIDN2=ON ' : '-DUSE_LIBIDN2=OFF '; - // lib:psl - $extra .= $this->builder->getLib('psl') ? '-DCURL_USE_LIBPSL=ON ' : '-DCURL_USE_LIBPSL=OFF '; - // lib:libcares - $extra .= $this->builder->getLib('libcares') ? '-DENABLE_ARES=ON ' : ''; + shell()->cd($this->source_dir)->exec('sed -i.save s@\${CMAKE_C_IMPLICIT_LINK_LIBRARIES}@@ ./CMakeLists.txt'); - FileSystem::resetDir($this->source_dir . '/build'); + UnixCMakeExecutor::create($this) + ->optionalLib('openssl', '-DCURL_USE_OPENSSL=ON -DCURL_CA_BUNDLE=OFF -DCURL_CA_PATH=OFF -DCURL_CA_FALLBACK=ON', '-DCURL_USE_OPENSSL=OFF -DCURL_ENABLE_SSL=OFF') + ->optionalLib('brotli', ...cmake_boolean_args('CURL_BROTLI')) + ->optionalLib('libssh2', fn ($lib) => "-DLIBSSH2_LIBRARY=\"{$lib->getStaticLibFiles(style: 'cmake')}\" -DLIBSSH2_INCLUDE_DIR={$lib->getIncludeDir()}", '-DCURL_USE_LIBSSH2=OFF') + ->optionalLib('nghttp2', fn ($lib) => "-DUSE_NGHTTP2=ON -DNGHTTP2_LIBRARY=\"{$lib->getStaticLibFiles(style: 'cmake')}\" -DNGHTTP2_INCLUDE_DIR={$lib->getIncludeDir()}", '-DUSE_NGHTTP2=OFF') + ->optionalLib('nghttp3', fn ($lib) => "-DUSE_NGHTTP3=ON -DNGHTTP3_LIBRARY=\"{$lib->getStaticLibFiles(style: 'cmake')}\" -DNGHTTP3_INCLUDE_DIR={$lib->getIncludeDir()}", '-DUSE_NGHTTP3=OFF') + ->optionalLib('ldap', ...cmake_boolean_args('CURL_DISABLE_LDAP', true)) + ->optionalLib('zstd', ...cmake_boolean_args('CURL_ZSTD')) + ->optionalLib('idn2', ...cmake_boolean_args('USE_LIBIDN2')) + ->optionalLib('psl', ...cmake_boolean_args('CURL_USE_LIBPSL')) + ->optionalLib('libcares', '-DENABLE_ARES=ON') + ->addConfigureArgs( + '-DBUILD_CURL_EXE=OFF', + '-DBUILD_LIBCURL_DOCS=OFF', + ) + ->build(); - // compile! - shell()->cd($this->source_dir . '/build') - ->setEnv([ - 'CFLAGS' => $this->getLibExtraCFlags(), - 'LDFLAGS' => $this->getLibExtraLdFlags(), - 'LIBS' => $this->getLibExtraLibs(), - ]) - ->exec('sed -i.save s@\${CMAKE_C_IMPLICIT_LINK_LIBRARIES}@@ ../CMakeLists.txt') - ->execWithEnv("cmake {$this->builder->makeCmakeArgs()} -DBUILD_CURL_EXE=OFF -DBUILD_LIBCURL_DOCS=OFF {$extra} ..") - ->execWithEnv("make -j{$this->builder->concurrency}") - ->execWithEnv('make install'); // patch pkgconf $this->patchPkgconfPrefix(['libcurl.pc']); FileSystem::replaceFileStr( diff --git a/src/SPC/builder/unix/library/freetype.php b/src/SPC/builder/unix/library/freetype.php index 187ebeff..35e62602 100644 --- a/src/SPC/builder/unix/library/freetype.php +++ b/src/SPC/builder/unix/library/freetype.php @@ -8,6 +8,7 @@ use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; use SPC\exception\WrongUsageException; use SPC\store\FileSystem; +use SPC\util\executor\UnixCMakeExecutor; trait freetype { @@ -18,26 +19,18 @@ trait freetype */ protected function build(): void { - $extra = ''; + $cmake = UnixCMakeExecutor::create($this) + ->optionalLib('libpng', ...cmake_boolean_args('FT_DISABLE_PNG', true)) + ->optionalLib('bzip2', ...cmake_boolean_args('FT_DISABLE_BZIP2', true)) + ->optionalLib('brotli', ...cmake_boolean_args('FT_DISABLE_BROTLI', true)) + ->addConfigureArgs('-DFT_DISABLE_HARFBUZZ=ON'); + + // fix cmake 4.0 compatibility if (version_compare(get_cmake_version(), '4.0.0', '>=')) { - $extra .= '-DCMAKE_POLICY_VERSION_MINIMUM=3.12 '; + $cmake->addConfigureArgs('-DCMAKE_POLICY_VERSION_MINIMUM=3.12'); } - $extra .= $this->builder->getLib('libpng') ? '-DFT_DISABLE_PNG=OFF ' : '-DFT_DISABLE_PNG=ON '; - $extra .= $this->builder->getLib('bzip2') ? '-DFT_DISABLE_BZIP2=OFF ' : '-DFT_DISABLE_BZIP2=ON '; - $extra .= $this->builder->getLib('brotli') ? '-DFT_DISABLE_BROTLI=OFF ' : '-DFT_DISABLE_BROTLI=ON '; - FileSystem::resetDir($this->source_dir . '/build'); - shell()->cd($this->source_dir . '/build') - ->setEnv([ - 'CFLAGS' => $this->getLibExtraCFlags(), - 'LDFLAGS' => $this->getLibExtraLdFlags(), - 'LIBS' => $this->getLibExtraLibs(), - ]) - ->execWithEnv( - "cmake {$this->builder->makeCmakeArgs()} -DFT_DISABLE_HARFBUZZ=ON {$extra}.." - ) - ->execWithEnv('make clean') - ->execWithEnv("make -j{$this->builder->concurrency}") - ->execWithEnv('make install'); + + $cmake->build(); $this->patchPkgconfPrefix(['freetype2.pc']); FileSystem::replaceFileStr( diff --git a/src/SPC/builder/unix/library/gettext.php b/src/SPC/builder/unix/library/gettext.php index 01c12519..15a6b6c7 100644 --- a/src/SPC/builder/unix/library/gettext.php +++ b/src/SPC/builder/unix/library/gettext.php @@ -16,15 +16,9 @@ trait gettext $cflags = $this->builder->getOption('enable-zts') ? '-lpthread -D_REENTRANT' : ''; $ldflags = $this->builder->getOption('enable-zts') ? '-lpthread' : ''; - $ldl = $this->builder->getLib('libgomp') && getenv('SPC_LIBC') === 'glibc' ? '-ldl' : ''; - - shell()->cd($this->source_dir) - ->setEnv([ - 'CFLAGS' => "{$this->getLibExtraCFlags()} {$cflags}", - 'LDFLAGS' => trim($this->getLibExtraLdFlags() . ' ' . $ldflags . ' ' . $ldl), - 'LIBS' => $this->getLibExtraLibs(), - ]) - ->execWithEnv( + shell()->cd($this->source_dir)->initializeEnv($this) + ->appendEnv(['CFLAGS' => $cflags, 'LDFLAGS' => $ldflags]) + ->exec( './configure ' . '--enable-static ' . '--disable-shared ' . @@ -37,9 +31,9 @@ trait gettext '--with-libiconv-prefix=' . BUILD_ROOT_PATH . ' ' . '--prefix=' . BUILD_ROOT_PATH ) - ->execWithEnv('make clean') - ->execWithEnv("make -j{$this->builder->concurrency}") - ->execWithEnv('make install'); + ->exec('make clean') + ->exec("make -j{$this->builder->concurrency}") + ->exec('make install'); $this->patchLaDependencyPrefix(['libintl.la']); } } diff --git a/src/SPC/builder/unix/library/gmp.php b/src/SPC/builder/unix/library/gmp.php index e458401c..57c58018 100644 --- a/src/SPC/builder/unix/library/gmp.php +++ b/src/SPC/builder/unix/library/gmp.php @@ -15,19 +15,10 @@ trait gmp */ protected function build(): void { - shell()->cd($this->source_dir) - ->setEnv([ - 'CFLAGS' => $this->getLibExtraCFlags(), - 'LDFLAGS' => $this->getLibExtraLdFlags(), - 'LIBS' => $this->getLibExtraLibs(), - ]) - ->execWithEnv( - './configure ' . - '--enable-static --disable-shared --with-pic ' . - '--prefix=' - ) - ->execWithEnv('make clean') - ->execWithEnv("make -j{$this->builder->concurrency}") + shell()->cd($this->source_dir)->initializeEnv($this) + ->exec('./configure --enable-static --disable-shared --with-pic --prefix=') + ->exec('make clean') + ->exec("make -j{$this->builder->concurrency}") ->exec('make install DESTDIR=' . BUILD_ROOT_PATH); $this->patchPkgconfPrefix(['gmp.pc']); } diff --git a/src/SPC/builder/unix/library/gmssl.php b/src/SPC/builder/unix/library/gmssl.php index 5e2fe153..89fc5207 100644 --- a/src/SPC/builder/unix/library/gmssl.php +++ b/src/SPC/builder/unix/library/gmssl.php @@ -4,29 +4,12 @@ declare(strict_types=1); namespace SPC\builder\unix\library; -use SPC\exception\FileSystemException; -use SPC\exception\RuntimeException; -use SPC\store\FileSystem; +use SPC\util\executor\UnixCMakeExecutor; trait gmssl { - /** - * @throws FileSystemException - * @throws RuntimeException - */ protected function build(): void { - // CMake needs a clean build directory - FileSystem::resetDir($this->source_dir . '/build'); - // Start build - shell()->cd($this->source_dir . '/build') - ->setEnv([ - 'CFLAGS' => $this->getLibExtraCFlags(), - 'LDFLAGS' => $this->getLibExtraLdFlags(), - 'LIBS' => $this->getLibExtraLibs(), - ]) - ->execWithEnv("cmake {$this->builder->makeCmakeArgs()} ..") - ->execWithEnv("cmake --build . -j {$this->builder->concurrency}") - ->execWithEnv('make install'); + UnixCMakeExecutor::create($this)->build(); } } diff --git a/src/SPC/builder/unix/library/imagemagick.php b/src/SPC/builder/unix/library/imagemagick.php index 78bcced9..1284305c 100644 --- a/src/SPC/builder/unix/library/imagemagick.php +++ b/src/SPC/builder/unix/library/imagemagick.php @@ -49,14 +49,9 @@ trait imagemagick // libxml iconv patch $required_libs .= $this instanceof MacOSLibraryBase ? ('-liconv') : ''; - shell()->cd($this->source_dir) - ->setEnv([ - 'CFLAGS' => $this->getLibExtraCFlags(), - 'LDFLAGS' => $this->getLibExtraLdFlags() ?: $ldflags, - 'LIBS' => $this->getLibExtraLibs() ?: $required_libs, - 'PKG_CONFIG' => '$PKG_CONFIG --static', - ]) - ->execWithEnv( + shell()->cd($this->source_dir)->initializeEnv($this) + ->appendEnv(['LDFLAGS' => $ldflags, 'LIBS' => $required_libs, 'PKG_CONFIG' => '$PKG_CONFIG --static']) + ->exec( './configure ' . '--enable-static --disable-shared --with-pic ' . $extra . diff --git a/src/SPC/builder/unix/library/ldap.php b/src/SPC/builder/unix/library/ldap.php index 3a05e3df..501654de 100644 --- a/src/SPC/builder/unix/library/ldap.php +++ b/src/SPC/builder/unix/library/ldap.php @@ -26,14 +26,9 @@ trait ldap $alt .= $this->builder->getLib('libsodium') ? '--with-argon2=libsodium ' : '--enable-argon2=no '; f_putenv('PKG_CONFIG=' . BUILD_ROOT_PATH . '/bin/pkg-config'); f_putenv('PKG_CONFIG_PATH=' . BUILD_LIB_PATH . '/pkgconfig'); - $ldflags = '-L' . BUILD_LIB_PATH; - shell()->cd($this->source_dir) - ->setEnv([ - 'CFLAGS' => $this->getLibExtraCFlags(), - 'LDFLAGS' => $this->getLibExtraLdFlags() ?: $ldflags, - 'LIBS' => $this->getLibExtraLibs(), - ]) - ->execWithEnv( + shell()->cd($this->source_dir)->initializeEnv($this) + ->appendEnv(['LDFLAGS' => "-L{$this->getLibDir()}"]) + ->exec( $this->builder->makeAutoconfFlags(AUTOCONF_CPPFLAGS) . ' ./configure ' . '--enable-static ' . diff --git a/src/SPC/builder/unix/library/libacl.php b/src/SPC/builder/unix/library/libacl.php index 7e74c947..7a371f9e 100644 --- a/src/SPC/builder/unix/library/libacl.php +++ b/src/SPC/builder/unix/library/libacl.php @@ -29,16 +29,12 @@ trait libacl */ protected function build(): void { - shell()->cd($this->source_dir) - ->setEnv([ - 'CFLAGS' => trim('-I' . BUILD_INCLUDE_PATH . ' ' . $this->getLibExtraCFlags()), - 'LDFLAGS' => trim('-L' . BUILD_LIB_PATH . ' ' . $this->getLibExtraLdFlags()), - 'LIBS' => $this->getLibExtraLibs(), - ]) - ->execWithEnv('libtoolize --force --copy') - ->execWithEnv('./autogen.sh || autoreconf -if') - ->execWithEnv('./configure --prefix= --enable-static --disable-shared --disable-tests --disable-nls --with-pic') - ->execWithEnv("make -j {$this->builder->concurrency}") + shell()->cd($this->source_dir)->initializeEnv($this) + ->appendEnv(['CFLAGS' => "-I{$this->getIncludeDir()}", 'LDFLAGS' => "-L{$this->getLibDir()}"]) + ->exec('libtoolize --force --copy') + ->exec('./autogen.sh || autoreconf -if') + ->exec('./configure --prefix= --enable-static --disable-shared --disable-tests --disable-nls --with-pic') + ->exec("make -j {$this->builder->concurrency}") ->exec('make install DESTDIR=' . BUILD_ROOT_PATH); $this->patchPkgconfPrefix(['libacl.pc'], PKGCONF_PATCH_PREFIX); diff --git a/src/SPC/builder/unix/library/libaom.php b/src/SPC/builder/unix/library/libaom.php index 38e0b95a..ab5c22b8 100644 --- a/src/SPC/builder/unix/library/libaom.php +++ b/src/SPC/builder/unix/library/libaom.php @@ -6,7 +6,7 @@ namespace SPC\builder\unix\library; use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; -use SPC\store\FileSystem; +use SPC\util\executor\UnixCMakeExecutor; trait libaom { @@ -16,13 +16,10 @@ trait libaom */ protected function build(): void { - // CMake needs a clean build directory - FileSystem::resetDir($this->source_dir . '/builddir'); - // Start build - shell()->cd($this->source_dir . '/builddir') - ->exec("cmake {$this->builder->makeCmakeArgs()} -DAOM_TARGET_CPU=generic ..") - ->exec("cmake --build . -j {$this->builder->concurrency}") - ->exec('make install'); + UnixCMakeExecutor::create($this) + ->setBuildDir("{$this->source_dir}/builddir") + ->addConfigureArgs('-DAOM_TARGET_CPU=generic') + ->build(); $this->patchPkgconfPrefix(['aom.pc']); } } diff --git a/src/SPC/builder/unix/library/libargon2.php b/src/SPC/builder/unix/library/libargon2.php index e2dba687..4c760095 100644 --- a/src/SPC/builder/unix/library/libargon2.php +++ b/src/SPC/builder/unix/library/libargon2.php @@ -10,15 +10,10 @@ trait libargon2 { protected function build() { - shell()->cd($this->source_dir) - ->setEnv([ - 'CFLAGS' => $this->getLibExtraCFlags(), - 'LDFLAGS' => $this->getLibExtraLdFlags(), - 'LIBS' => $this->getLibExtraLibs(), - ]) + shell()->cd($this->source_dir)->initializeEnv($this) ->exec("make PREFIX='' clean") - ->execWithEnv("make -j{$this->builder->concurrency} PREFIX=''") - ->execWithEnv("make install PREFIX='' DESTDIR=" . BUILD_ROOT_PATH); + ->exec("make -j{$this->builder->concurrency} PREFIX=''") + ->exec("make install PREFIX='' DESTDIR=" . BUILD_ROOT_PATH); $this->patchPkgconfPrefix(['libargon2.pc']); diff --git a/src/SPC/builder/unix/library/libavif.php b/src/SPC/builder/unix/library/libavif.php index 3c01c102..cbec640b 100644 --- a/src/SPC/builder/unix/library/libavif.php +++ b/src/SPC/builder/unix/library/libavif.php @@ -7,7 +7,7 @@ namespace SPC\builder\unix\library; use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; use SPC\exception\WrongUsageException; -use SPC\store\FileSystem; +use SPC\util\executor\UnixCMakeExecutor; trait libavif { @@ -18,18 +18,9 @@ trait libavif */ protected function build(): void { - // CMake needs a clean build directory - FileSystem::resetDir($this->source_dir . '/build'); - // Start build - shell()->cd($this->source_dir . '/build') - ->setEnv([ - 'CFLAGS' => $this->getLibExtraCFlags(), - 'LDFLAGS' => $this->getLibExtraLdFlags(), - 'LIBS' => $this->getLibExtraLibs(), - ]) - ->execWithEnv("cmake {$this->builder->makeCmakeArgs()} -DAVIF_LIBYUV=OFF ..") - ->execWithEnv("cmake --build . -j {$this->builder->concurrency}") - ->execWithEnv('make install'); + UnixCMakeExecutor::create($this) + ->addConfigureArgs('-DAVIF_LIBYUV=OFF') + ->build(); // patch pkgconfig $this->patchPkgconfPrefix(['libavif.pc']); $this->cleanLaFiles(); diff --git a/src/SPC/builder/unix/library/libcares.php b/src/SPC/builder/unix/library/libcares.php index 94871927..61683bbf 100644 --- a/src/SPC/builder/unix/library/libcares.php +++ b/src/SPC/builder/unix/library/libcares.php @@ -24,15 +24,10 @@ trait libcares */ protected function build(): void { - shell()->cd($this->source_dir) - ->setEnv([ - 'CFLAGS' => $this->getLibExtraCFlags(), - 'LDFLAGS' => $this->getLibExtraLdFlags(), - 'LIBS' => $this->getLibExtraLibs(), - ]) - ->execWithEnv('./configure --prefix= --enable-static --disable-shared --disable-tests --with-pic') - ->execWithEnv("make -j {$this->builder->concurrency}") - ->execWithEnv('make install DESTDIR=' . BUILD_ROOT_PATH); + shell()->cd($this->source_dir)->initializeEnv($this) + ->exec('./configure --prefix= --enable-static --disable-shared --disable-tests --with-pic') + ->exec("make -j {$this->builder->concurrency}") + ->exec('make install DESTDIR=' . BUILD_ROOT_PATH); $this->patchPkgconfPrefix(['libcares.pc'], PKGCONF_PATCH_PREFIX); } diff --git a/src/SPC/builder/unix/library/libde265.php b/src/SPC/builder/unix/library/libde265.php index 0f7d44a1..eaba0cfc 100644 --- a/src/SPC/builder/unix/library/libde265.php +++ b/src/SPC/builder/unix/library/libde265.php @@ -6,7 +6,7 @@ namespace SPC\builder\unix\library; use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; -use SPC\store\FileSystem; +use SPC\util\executor\UnixCMakeExecutor; trait libde265 { @@ -16,13 +16,9 @@ trait libde265 */ protected function build(): void { - // CMake needs a clean build directory - FileSystem::resetDir($this->source_dir . '/build'); - // Start build - shell()->cd($this->source_dir . '/build') - ->exec("cmake {$this->builder->makeCmakeArgs()} ..") - ->exec("cmake --build . -j {$this->builder->concurrency}") - ->exec('make install'); + UnixCMakeExecutor::create($this) + ->addConfigureArgs('-DENABLE_SDL=OFF') + ->build(); $this->patchPkgconfPrefix(['libde265.pc']); } } diff --git a/src/SPC/builder/unix/library/libevent.php b/src/SPC/builder/unix/library/libevent.php index 58b1b879..55889d1d 100644 --- a/src/SPC/builder/unix/library/libevent.php +++ b/src/SPC/builder/unix/library/libevent.php @@ -7,6 +7,7 @@ namespace SPC\builder\unix\library; use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; use SPC\store\FileSystem; +use SPC\util\executor\UnixCMakeExecutor; trait libevent { @@ -39,31 +40,19 @@ trait libevent */ protected function build(): void { - // CMake needs a clean build directory - $extra = ''; + $cmake = UnixCMakeExecutor::create($this) + ->addConfigureArgs( + '-DEVENT__LIBRARY_TYPE=STATIC', + '-DEVENT__DISABLE_BENCHMARK=ON', + '-DEVENT__DISABLE_THREAD_SUPPORT=ON', + '-DEVENT__DISABLE_TESTS=ON', + '-DEVENT__DISABLE_SAMPLES=ON', + '-DEVENT__DISABLE_MBEDTLS=ON ', + ); if (version_compare(get_cmake_version(), '4.0.0', '>=')) { - $extra .= '-DCMAKE_POLICY_VERSION_MINIMUM=3.10 '; + $cmake->addConfigureArgs('-DCMAKE_POLICY_VERSION_MINIMUM=3.10'); } - FileSystem::resetDir($this->source_dir . '/build'); - // Start build - shell()->cd($this->source_dir . '/build') - ->setEnv([ - 'CFLAGS' => $this->getLibExtraCFlags(), - 'LDFLAGS' => $this->getLibExtraLdFlags(), - 'LIBS' => $this->getLibExtraLibs(), - ]) - ->execWithEnv( - "cmake {$this->builder->makeCmakeArgs()} {$extra}" . - '-DEVENT__LIBRARY_TYPE=STATIC ' . - '-DEVENT__DISABLE_BENCHMARK=ON ' . - '-DEVENT__DISABLE_THREAD_SUPPORT=ON ' . - '-DEVENT__DISABLE_MBEDTLS=ON ' . - '-DEVENT__DISABLE_TESTS=ON ' . - '-DEVENT__DISABLE_SAMPLES=ON ' . - '..' - ) - ->execWithEnv("cmake --build . -j {$this->builder->concurrency}") - ->exec('make install'); + $cmake->build(); $this->patchPkgconfPrefix(['libevent.pc', 'libevent_core.pc', 'libevent_extra.pc', 'libevent_openssl.pc']); diff --git a/src/SPC/builder/unix/library/libheif.php b/src/SPC/builder/unix/library/libheif.php index 9e92cf22..131a330d 100644 --- a/src/SPC/builder/unix/library/libheif.php +++ b/src/SPC/builder/unix/library/libheif.php @@ -6,7 +6,7 @@ namespace SPC\builder\unix\library; use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; -use SPC\store\FileSystem; +use SPC\util\executor\UnixCMakeExecutor; trait libheif { @@ -16,22 +16,16 @@ trait libheif */ protected function build(): void { - // CMake needs a clean build directory - FileSystem::resetDir($this->source_dir . '/build'); - // Start build - shell()->cd($this->source_dir . '/build') - ->exec( - "cmake {$this->builder->makeCmakeArgs()} " . - '--preset=release ' . - '-DWITH_EXAMPLES=OFF ' . - '-DWITH_GDK_PIXBUF=OFF ' . - '-DBUILD_TESTING=OFF ' . - '-DWITH_LIBSHARPYUV=ON ' . // optional: libwebp - '-DENABLE_PLUGIN_LOADING=OFF ' . - '..' + UnixCMakeExecutor::create($this) + ->addConfigureArgs( + '--preset=release', + '-DWITH_EXAMPLES=OFF', + '-DWITH_GDK_PIXBUF=OFF', + '-DBUILD_TESTING=OFF', + '-DWITH_LIBSHARPYUV=ON', // optional: libwebp + '-DENABLE_PLUGIN_LOADING=OFF', ) - ->exec("cmake --build . -j {$this->builder->concurrency}") - ->exec('make install'); + ->build(); $this->patchPkgconfPrefix(['libheif.pc']); } } diff --git a/src/SPC/builder/unix/library/libiconv.php b/src/SPC/builder/unix/library/libiconv.php index a4f77d98..36ef136e 100644 --- a/src/SPC/builder/unix/library/libiconv.php +++ b/src/SPC/builder/unix/library/libiconv.php @@ -8,15 +8,8 @@ trait libiconv { protected function build(): void { - [,,$destdir] = SEPARATED_PATH; - - shell()->cd($this->source_dir) - ->setEnv([ - 'CFLAGS' => $this->getLibExtraCFlags(), - 'LDFLAGS' => $this->getLibExtraLdFlags(), - 'LIBS' => $this->getLibExtraLibs(), - ]) - ->execWithEnv( + shell()->cd($this->source_dir)->initializeEnv($this) + ->exec( './configure ' . '--enable-static ' . '--disable-shared ' . @@ -24,13 +17,10 @@ trait libiconv '--enable-extra-encodings ' . '--prefix=' ) - ->execWithEnv('make clean') - ->execWithEnv("make -j{$this->builder->concurrency}") - ->execWithEnv('make install DESTDIR=' . $destdir); + ->exec('make clean') + ->exec("make -j{$this->builder->concurrency}") + ->exec('make install DESTDIR=' . BUILD_ROOT_PATH); - if (file_exists(BUILD_BIN_PATH . '/iconv')) { - unlink(BUILD_BIN_PATH . '/iconv'); - } $this->patchLaDependencyPrefix(['libiconv.la']); } } diff --git a/src/SPC/builder/unix/library/libjpeg.php b/src/SPC/builder/unix/library/libjpeg.php index c4f9833d..3f8aff9e 100644 --- a/src/SPC/builder/unix/library/libjpeg.php +++ b/src/SPC/builder/unix/library/libjpeg.php @@ -7,7 +7,7 @@ namespace SPC\builder\unix\library; use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; use SPC\exception\WrongUsageException; -use SPC\store\FileSystem; +use SPC\util\executor\UnixCMakeExecutor; trait libjpeg { @@ -18,18 +18,12 @@ trait libjpeg */ protected function build(): void { - // CMake needs a clean build directory - FileSystem::resetDir($this->source_dir . '/build'); - // Start build - shell()->cd($this->source_dir . '/build') - ->exec( - "cmake {$this->builder->makeCmakeArgs()} " . - '-DENABLE_STATIC=ON ' . - '-DENABLE_SHARED=OFF ' . - '..' + UnixCMakeExecutor::create($this) + ->addConfigureArgs( + '-DENABLE_STATIC=ON', + '-DENABLE_SHARED=OFF', ) - ->exec("cmake --build . -j {$this->builder->concurrency}") - ->exec('make install'); + ->build(); // patch pkgconfig $this->patchPkgconfPrefix(['libjpeg.pc', 'libturbojpeg.pc']); $this->cleanLaFiles(); diff --git a/src/SPC/builder/unix/library/liblz4.php b/src/SPC/builder/unix/library/liblz4.php index 39c24512..73108d95 100644 --- a/src/SPC/builder/unix/library/liblz4.php +++ b/src/SPC/builder/unix/library/liblz4.php @@ -17,15 +17,10 @@ trait liblz4 protected function build(): void { - shell()->cd($this->source_dir) - ->setEnv([ - 'CFLAGS' => $this->getLibExtraCFlags(), - 'LDFLAGS' => $this->getLibExtraLdFlags(), - 'LIBS' => $this->getLibExtraLibs(), - ]) - ->execWithEnv("make PREFIX='' clean") - ->execWithEnv("make -j{$this->builder->concurrency} PREFIX=''") - ->execWithEnv("make install PREFIX='' DESTDIR=" . BUILD_ROOT_PATH); + shell()->cd($this->source_dir)->initializeEnv($this) + ->exec("make PREFIX='' clean") + ->exec("make -j{$this->builder->concurrency} PREFIX=''") + ->exec("make install PREFIX='' DESTDIR=" . BUILD_ROOT_PATH); $this->patchPkgconfPrefix(['liblz4.pc']); diff --git a/src/SPC/builder/unix/library/librabbitmq.php b/src/SPC/builder/unix/library/librabbitmq.php index d4044b46..1e1e64d1 100644 --- a/src/SPC/builder/unix/library/librabbitmq.php +++ b/src/SPC/builder/unix/library/librabbitmq.php @@ -6,7 +6,7 @@ namespace SPC\builder\unix\library; use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; -use SPC\store\FileSystem; +use SPC\util\executor\UnixCMakeExecutor; trait librabbitmq { @@ -16,12 +16,6 @@ trait librabbitmq */ protected function build(): void { - // CMake needs a clean build directory - FileSystem::resetDir($this->source_dir . '/build'); - // Start build - shell()->cd($this->source_dir . '/build') - ->exec("cmake {$this->builder->makeCmakeArgs()} ..") - ->exec("cmake --build . -j {$this->builder->concurrency}") - ->exec('make install'); + UnixCMakeExecutor::create($this)->addConfigureArgs('-DBUILD_STATIC_LIBS=ON')->build(); } } diff --git a/src/SPC/builder/unix/library/libssh2.php b/src/SPC/builder/unix/library/libssh2.php index f2132fc8..26337ee4 100644 --- a/src/SPC/builder/unix/library/libssh2.php +++ b/src/SPC/builder/unix/library/libssh2.php @@ -6,7 +6,7 @@ namespace SPC\builder\unix\library; use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; -use SPC\store\FileSystem; +use SPC\util\executor\UnixCMakeExecutor; trait libssh2 { @@ -16,19 +16,14 @@ trait libssh2 */ protected function build(): void { - $enable_zlib = $this->builder->getLib('zlib') !== null ? 'ON' : 'OFF'; - - FileSystem::resetDir($this->source_dir . '/build'); - shell()->cd($this->source_dir . '/build') - ->exec( - "cmake {$this->builder->makeCmakeArgs()} " . - '-DBUILD_EXAMPLES=OFF ' . - '-DBUILD_TESTING=OFF ' . - "-DENABLE_ZLIB_COMPRESSION={$enable_zlib} " . - '..' + UnixCMakeExecutor::create($this) + ->optionalLib('zlib', ...cmake_boolean_args('ENABLE_ZLIB_COMPRESSION')) + ->addConfigureArgs( + '-DBUILD_EXAMPLES=OFF', + '-DBUILD_TESTING=OFF' ) - ->exec("cmake --build . -j {$this->builder->concurrency}") - ->exec('make install'); + ->build(); + $this->patchPkgconfPrefix(['libssh2.pc']); } } diff --git a/src/SPC/builder/unix/library/libtiff.php b/src/SPC/builder/unix/library/libtiff.php index d2264dda..8f59fcae 100644 --- a/src/SPC/builder/unix/library/libtiff.php +++ b/src/SPC/builder/unix/library/libtiff.php @@ -22,28 +22,17 @@ trait libtiff // We disabled lzma, zstd, webp, libdeflate by default to reduce the size of the binary $extra_libs .= ' --disable-lzma --disable-zstd --disable-webp --disable-libdeflate'; - $shell = shell()->cd($this->source_dir) - ->setEnv([ - 'CFLAGS' => $this->getLibExtraCFlags(), - 'LDFLAGS' => $this->getLibExtraLdFlags(), - 'LIBS' => $this->getLibExtraLibs(), - ]) - ->execWithEnv( + $shell = shell()->cd($this->source_dir)->initializeEnv($this) + ->exec( './configure ' . '--enable-static --disable-shared --with-pic ' . "{$extra_libs} " . '--disable-cxx ' . '--prefix=' - ); - - // TODO: Remove this check when https://gitlab.com/libtiff/libtiff/-/merge_requests/635 will be merged and released - if (file_exists($this->source_dir . '/html')) { - $shell->execWithEnv('make clean'); - } - - $shell - ->execWithEnv("make -j{$this->builder->concurrency}") - ->execWithEnv('make install DESTDIR=' . BUILD_ROOT_PATH); + ) + ->exec('make clean') + ->exec("make -j{$this->builder->concurrency}") + ->exec('make install DESTDIR=' . BUILD_ROOT_PATH); $this->patchPkgconfPrefix(['libtiff-4.pc']); } } diff --git a/src/SPC/builder/unix/library/libuuid.php b/src/SPC/builder/unix/library/libuuid.php index cb13c66b..197e0f80 100644 --- a/src/SPC/builder/unix/library/libuuid.php +++ b/src/SPC/builder/unix/library/libuuid.php @@ -5,21 +5,17 @@ declare(strict_types=1); namespace SPC\builder\unix\library; use SPC\exception\FileSystemException; -use SPC\exception\RuntimeException; use SPC\store\FileSystem; +use SPC\util\executor\UnixCMakeExecutor; trait libuuid { /** * @throws FileSystemException - * @throws RuntimeException */ protected function build(): void { - FileSystem::resetDir($this->source_dir . '/build'); - shell()->cd($this->source_dir . '/build') - ->exec("cmake {$this->builder->makeCmakeArgs()} ..") - ->exec("cmake --build . -j {$this->builder->concurrency}"); + UnixCMakeExecutor::create($this)->toStep(2)->build(); copy($this->source_dir . '/build/libuuid.a', BUILD_LIB_PATH . '/libuuid.a'); FileSystem::createDir(BUILD_INCLUDE_PATH . '/uuid'); copy($this->source_dir . '/uuid.h', BUILD_INCLUDE_PATH . '/uuid/uuid.h'); diff --git a/src/SPC/builder/unix/library/libuv.php b/src/SPC/builder/unix/library/libuv.php index fda11c0a..b4b5e01c 100644 --- a/src/SPC/builder/unix/library/libuv.php +++ b/src/SPC/builder/unix/library/libuv.php @@ -6,7 +6,7 @@ namespace SPC\builder\unix\library; use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; -use SPC\store\FileSystem; +use SPC\util\executor\UnixCMakeExecutor; trait libuv { @@ -16,13 +16,9 @@ trait libuv */ protected function build(): void { - // CMake needs a clean build directory - FileSystem::resetDir($this->source_dir . '/build'); - // Start build - shell()->cd($this->source_dir . '/build') - ->exec("cmake {$this->builder->makeCmakeArgs()} -DLIBUV_BUILD_SHARED=OFF ..") - ->exec("cmake --build . -j {$this->builder->concurrency}") - ->exec('make install'); + UnixCMakeExecutor::create($this) + ->addConfigureArgs('-DLIBUV_BUILD_SHARED=OFF') + ->build(); // patch pkgconfig $this->patchPkgconfPrefix(['libuv-static.pc']); } diff --git a/src/SPC/builder/unix/library/libwebp.php b/src/SPC/builder/unix/library/libwebp.php index 29076c6d..e4f45eb4 100644 --- a/src/SPC/builder/unix/library/libwebp.php +++ b/src/SPC/builder/unix/library/libwebp.php @@ -7,7 +7,7 @@ namespace SPC\builder\unix\library; use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; use SPC\exception\WrongUsageException; -use SPC\store\FileSystem; +use SPC\util\executor\UnixCMakeExecutor; trait libwebp { @@ -18,13 +18,9 @@ trait libwebp */ protected function build(): void { - // CMake needs a clean build directory - FileSystem::resetDir($this->source_dir . '/build'); - // Start build - shell()->cd($this->source_dir . '/build') - ->exec("cmake {$this->builder->makeCmakeArgs()} -DWEBP_BUILD_EXTRAS=ON ..") - ->exec("cmake --build . -j {$this->builder->concurrency}") - ->exec('make install'); + UnixCMakeExecutor::create($this) + ->addConfigureArgs('-DWEBP_BUILD_EXTRAS=ON') + ->build(); // patch pkgconfig $this->patchPkgconfPrefix(['libsharpyuv.pc', 'libwebp.pc', 'libwebpdecoder.pc', 'libwebpdemux.pc', 'libwebpmux.pc'], PKGCONF_PATCH_PREFIX | PKGCONF_PATCH_LIBDIR); $this->patchPkgconfPrefix(['libsharpyuv.pc'], PKGCONF_PATCH_CUSTOM, ['/^includedir=.*$/m', 'includedir=${prefix}/include/webp']); diff --git a/src/SPC/builder/unix/library/libxml2.php b/src/SPC/builder/unix/library/libxml2.php new file mode 100644 index 00000000..72a418ef --- /dev/null +++ b/src/SPC/builder/unix/library/libxml2.php @@ -0,0 +1,42 @@ +optionalLib('zlib', "-DLIBXML2_WITH_ZLIB=ON -DZLIB_LIBRARY={$this->getLibDir()}/libz.a -DZLIB_INCLUDE_DIR={$this->getIncludeDir()}", '-DLIBXML2_WITH_ZLIB=OFF') + ->optionalLib('icu', ...cmake_boolean_args('LIBXML2_WITH_ICU')) + ->optionalLib('xz', ...cmake_boolean_args('LIBXML2_WITH_LZMA')) + ->addConfigureArgs( + '-DLIBXML2_WITH_ICONV=ON', + '-DLIBXML2_WITH_PYTHON=OFF', + '-DLIBXML2_WITH_PROGRAMS=OFF', + '-DLIBXML2_WITH_TESTS=OFF', + ); + + if ($this instanceof LinuxLibraryBase) { + $cmake->addConfigureArgs('-DIconv_IS_BUILD_IN=OFF'); + } + + $cmake->build(); + + FileSystem::replaceFileStr( + BUILD_LIB_PATH . '/pkgconfig/libxml-2.0.pc', + '-licudata -licui18n -licuuc', + '-licui18n -licuuc -licudata' + ); + } +} diff --git a/src/SPC/builder/unix/library/libxslt.php b/src/SPC/builder/unix/library/libxslt.php index 8a9bafaa..10975145 100644 --- a/src/SPC/builder/unix/library/libxslt.php +++ b/src/SPC/builder/unix/library/libxslt.php @@ -24,13 +24,13 @@ trait libxslt $required_libs .= ' ' . $dep->getStaticLibFiles(); } } - shell()->cd($this->source_dir) - ->setEnv([ - 'CFLAGS' => trim($this->getLibExtraCFlags() . ' -I' . BUILD_INCLUDE_PATH), - 'LDFLAGS' => trim($this->getLibExtraLdFlags() . ' -L' . BUILD_LIB_PATH), - 'LIBS' => trim($this->getLibExtraLibs() . "{$required_libs} -lstdc++"), + shell()->cd($this->source_dir)->initializeEnv($this) + ->appendEnv([ + 'CFLAGS' => "-I{$this->getIncludeDir()}", + 'LDFLAGS' => "-L{$this->getLibDir()}", + 'LIBS' => "{$required_libs} -lstdc++", ]) - ->execWithEnv( + ->exec( "{$this->builder->getOption('library_path')} " . "{$this->builder->getOption('ld_library_path')} " . './configure ' . @@ -44,9 +44,9 @@ trait libxslt '--with-libxml-prefix=' . escapeshellarg(BUILD_ROOT_PATH) . ' ' . '--prefix=' ) - ->execWithEnv('make clean') - ->execWithEnv("make -j{$this->builder->concurrency}") - ->execWithEnv('make install DESTDIR=' . escapeshellarg(BUILD_ROOT_PATH)); + ->exec('make clean') + ->exec("make -j{$this->builder->concurrency}") + ->exec('make install DESTDIR=' . escapeshellarg(BUILD_ROOT_PATH)); $this->patchPkgconfPrefix(['libexslt.pc']); $this->patchLaDependencyPrefix(['libxslt.la', 'libexslt.la']); shell()->cd(BUILD_LIB_PATH) diff --git a/src/SPC/builder/unix/library/libyaml.php b/src/SPC/builder/unix/library/libyaml.php index 145f5b57..12ab3915 100644 --- a/src/SPC/builder/unix/library/libyaml.php +++ b/src/SPC/builder/unix/library/libyaml.php @@ -4,9 +4,8 @@ declare(strict_types=1); namespace SPC\builder\unix\library; -use SPC\exception\FileSystemException; -use SPC\exception\RuntimeException; use SPC\store\FileSystem; +use SPC\util\executor\UnixCMakeExecutor; trait libyaml { @@ -25,20 +24,12 @@ trait libyaml return null; } - /** - * @throws RuntimeException - * @throws FileSystemException - */ protected function build(): void { - $extra = ''; + $cmake = UnixCMakeExecutor::create($this)->addConfigureArgs('-DBUILD_TESTING=OFF'); if (version_compare(get_cmake_version(), '4.0.0', '>=')) { - $extra .= '-DCMAKE_POLICY_VERSION_MINIMUM=3.5'; + $cmake->addConfigureArgs('-DCMAKE_POLICY_VERSION_MINIMUM=3.5'); } - FileSystem::resetDir($this->source_dir . '/build'); - shell()->cd($this->source_dir . '/build') - ->exec("cmake {$this->builder->makeCmakeArgs()} {$extra} -DBUILD_TESTING=OFF ..") - ->exec("make -j{$this->builder->concurrency}") - ->exec('make install'); + $cmake->build(); } } diff --git a/src/SPC/builder/unix/library/libzip.php b/src/SPC/builder/unix/library/libzip.php index 9c00d6a2..a442129f 100644 --- a/src/SPC/builder/unix/library/libzip.php +++ b/src/SPC/builder/unix/library/libzip.php @@ -6,7 +6,7 @@ namespace SPC\builder\unix\library; use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; -use SPC\store\FileSystem; +use SPC\util\executor\UnixCMakeExecutor; trait libzip { @@ -16,31 +16,20 @@ trait libzip */ protected function build(): void { - $extra = ''; - // lib:bzip2 - $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 (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 '; - - FileSystem::resetDir($this->source_dir . '/build'); - shell()->cd($this->source_dir . '/build') - ->exec( - "cmake {$this->builder->makeCmakeArgs()} " . - '-DENABLE_GNUTLS=OFF ' . - '-DENABLE_MBEDTLS=OFF ' . - '-DBUILD_DOC=OFF ' . - '-DBUILD_EXAMPLES=OFF ' . - '-DBUILD_REGRESS=OFF ' . - '-DBUILD_TOOLS=OFF ' . - $extra . - '..' + UnixCMakeExecutor::create($this) + ->optionalLib('bzip2', ...cmake_boolean_args('ENABLE_BZIP2')) + ->optionalLib('xz', ...cmake_boolean_args('ENABLE_LZMA')) + ->optionalLib('openssl', ...cmake_boolean_args('ENABLE_OPENSSL')) + ->optionalLib('zstd', ...cmake_boolean_args('ENABLE_ZSTD')) + ->addConfigureArgs( + '-DENABLE_GNUTLS=OFF', + '-DENABLE_MBEDTLS=OFF', + '-DBUILD_DOC=OFF', + '-DBUILD_EXAMPLES=OFF', + '-DBUILD_REGRESS=OFF', + '-DBUILD_TOOLS=OFF', ) - ->exec("make -j{$this->builder->concurrency}") - ->exec('make install'); + ->build(); $this->patchPkgconfPrefix(['libzip.pc'], PKGCONF_PATCH_PREFIX); } } diff --git a/src/SPC/builder/unix/library/mimalloc.php b/src/SPC/builder/unix/library/mimalloc.php index bbf80bbd..78868856 100644 --- a/src/SPC/builder/unix/library/mimalloc.php +++ b/src/SPC/builder/unix/library/mimalloc.php @@ -4,28 +4,20 @@ declare(strict_types=1); namespace SPC\builder\unix\library; -use SPC\exception\FileSystemException; -use SPC\exception\RuntimeException; -use SPC\store\FileSystem; +use SPC\util\executor\UnixCMakeExecutor; trait mimalloc { - /** - * @throws RuntimeException - * @throws FileSystemException - */ protected function build(): void { - $args = ''; + $cmake = UnixCMakeExecutor::create($this) + ->addConfigureArgs( + '-DMI_BUILD_SHARED=OFF', + '-DMI_INSTALL_TOPLEVEL=ON' + ); if (getenv('SPC_LIBC') === 'musl') { - $args .= '-DMI_LIBC_MUSL=ON '; + $cmake->addConfigureArgs('-DMI_LIBC_MUSL=ON'); } - $args .= '-DMI_BUILD_SHARED=OFF '; - $args .= '-DMI_INSTALL_TOPLEVEL=ON '; - FileSystem::resetDir($this->source_dir . '/build'); - shell()->cd($this->source_dir . '/build') - ->execWithEnv("cmake {$this->builder->makeCmakeArgs()} {$args} ..") - ->execWithEnv("make -j{$this->builder->concurrency}") - ->execWithEnv('make install'); + $cmake->build(); } } diff --git a/src/SPC/builder/unix/library/ncurses.php b/src/SPC/builder/unix/library/ncurses.php index 0297afe2..7d33c76a 100644 --- a/src/SPC/builder/unix/library/ncurses.php +++ b/src/SPC/builder/unix/library/ncurses.php @@ -11,13 +11,8 @@ trait ncurses protected function build(): void { $filelist = FileSystem::scanDirFiles(BUILD_BIN_PATH, relative: true); - shell()->cd($this->source_dir) - ->setEnv([ - 'CFLAGS' => $this->getLibExtraCFlags(), - 'LDFLAGS' => $this->getLibExtraLdFlags(), - 'LIBS' => $this->getLibExtraLibs(), - ]) - ->execWithEnv( + shell()->cd($this->source_dir)->initializeEnv($this) + ->exec( './configure ' . '--enable-static ' . '--disable-shared ' . @@ -37,9 +32,9 @@ trait ncurses '--libdir=' . BUILD_ROOT_PATH . '/lib ' . '--prefix=' . BUILD_ROOT_PATH ) - ->execWithEnv('make clean') - ->execWithEnv("make -j{$this->builder->concurrency}") - ->execWithEnv('make install'); + ->exec('make clean') + ->exec("make -j{$this->builder->concurrency}") + ->exec('make install'); $final = FileSystem::scanDirFiles(BUILD_BIN_PATH, relative: true); // Remove the new files diff --git a/src/SPC/builder/unix/library/nghttp2.php b/src/SPC/builder/unix/library/nghttp2.php index 453f5876..e09832d9 100644 --- a/src/SPC/builder/unix/library/nghttp2.php +++ b/src/SPC/builder/unix/library/nghttp2.php @@ -40,13 +40,8 @@ trait nghttp2 [,,$destdir] = SEPARATED_PATH; - shell()->cd($this->source_dir) - ->setEnv([ - 'CFLAGS' => $this->getLibExtraCFlags(), - 'LDFLAGS' => $this->getLibExtraLdFlags(), - 'LIBS' => $this->getLibExtraLibs(), - ]) - ->execWithEnv( + shell()->cd($this->source_dir)->initializeEnv($this) + ->exec( './configure ' . '--enable-static ' . '--disable-shared ' . @@ -55,9 +50,9 @@ trait nghttp2 $args . ' ' . '--prefix=' ) - ->execWithEnv('make clean') - ->execWithEnv("make -j{$this->builder->concurrency}") - ->execWithEnv("make install DESTDIR={$destdir}"); + ->exec('make clean') + ->exec("make -j{$this->builder->concurrency}") + ->exec("make install DESTDIR={$destdir}"); $this->patchPkgconfPrefix(['libnghttp2.pc']); $this->patchLaDependencyPrefix(['libnghttp2.la']); } diff --git a/src/SPC/builder/unix/library/nghttp3.php b/src/SPC/builder/unix/library/nghttp3.php index 8eb00f5b..ca2862a2 100644 --- a/src/SPC/builder/unix/library/nghttp3.php +++ b/src/SPC/builder/unix/library/nghttp3.php @@ -15,13 +15,8 @@ trait nghttp3 */ protected function build(): void { - shell()->cd($this->source_dir) - ->setEnv([ - 'CFLAGS' => $this->getLibExtraCFlags(), - 'LDFLAGS' => $this->getLibExtraLdFlags(), - 'LIBS' => $this->getLibExtraLibs(), - ]) - ->execWithEnv( + shell()->cd($this->source_dir)->initializeEnv($this) + ->exec( './configure ' . '--enable-static ' . '--disable-shared ' . @@ -29,9 +24,9 @@ trait nghttp3 '--enable-lib-only ' . '--prefix=' ) - ->execWithEnv('make clean') - ->execWithEnv("make -j{$this->builder->concurrency}") - ->execWithEnv('make install DESTDIR=' . BUILD_ROOT_PATH); + ->exec('make clean') + ->exec("make -j{$this->builder->concurrency}") + ->exec('make install DESTDIR=' . BUILD_ROOT_PATH); $this->patchPkgconfPrefix(['libnghttp3.pc']); $this->patchLaDependencyPrefix(['libnghttp3.la']); } diff --git a/src/SPC/builder/unix/library/ngtcp2.php b/src/SPC/builder/unix/library/ngtcp2.php index bfe44900..94e9c570 100644 --- a/src/SPC/builder/unix/library/ngtcp2.php +++ b/src/SPC/builder/unix/library/ngtcp2.php @@ -30,13 +30,8 @@ trait ngtcp2 $args .= ' --with-libbrotlienc=yes LIBBROTLIENC_CFLAGS="-I' . BUILD_ROOT_PATH . '/include" LIBBROTLIENC_LIBS="' . $brotli->getStaticLibFiles() . '"'; } - shell()->cd($this->source_dir) - ->setEnv([ - 'CFLAGS' => $this->getLibExtraCFlags(), - 'LDFLAGS' => $this->getLibExtraLdFlags(), - 'LIBS' => $this->getLibExtraLibs(), - ]) - ->execWithEnv( + shell()->cd($this->source_dir)->initializeEnv($this) + ->exec( './configure ' . '--enable-static ' . '--disable-shared ' . @@ -45,9 +40,9 @@ trait ngtcp2 $args . ' ' . '--prefix=' ) - ->execWithEnv('make clean') - ->execWithEnv("make -j{$this->builder->concurrency}") - ->execWithEnv('make install DESTDIR=' . BUILD_ROOT_PATH); + ->exec('make clean') + ->exec("make -j{$this->builder->concurrency}") + ->exec('make install DESTDIR=' . BUILD_ROOT_PATH); $this->patchPkgconfPrefix(['libngtcp2.pc', 'libngtcp2_crypto_ossl.pc']); $this->patchLaDependencyPrefix(['libngtcp2.la', 'libngtcp2_crypto_ossl.la']); diff --git a/src/SPC/builder/unix/library/onig.php b/src/SPC/builder/unix/library/onig.php index 458e9c47..62e8f606 100644 --- a/src/SPC/builder/unix/library/onig.php +++ b/src/SPC/builder/unix/library/onig.php @@ -17,15 +17,10 @@ trait onig { [,,$destdir] = SEPARATED_PATH; - shell()->cd($this->source_dir) - ->setEnv([ - 'CFLAGS' => $this->getLibExtraCFlags(), - 'LDFLAGS' => $this->getLibExtraLdFlags(), - 'LIBS' => $this->getLibExtraLibs(), - ]) - ->execWithEnv('./configure --enable-static --disable-shared --enable-pic --prefix=') - ->execWithEnv('make clean') - ->execWithEnv("make -j{$this->builder->concurrency}") + shell()->cd($this->source_dir)->initializeEnv($this) + ->exec('./configure --enable-static --disable-shared --enable-pic --prefix=') + ->exec('make clean') + ->exec("make -j{$this->builder->concurrency}") ->exec("make install DESTDIR={$destdir}"); $this->patchPkgconfPrefix(['oniguruma.pc']); } diff --git a/src/SPC/builder/unix/library/pkgconfig.php b/src/SPC/builder/unix/library/pkgconfig.php index 9478d9ea..51fa586b 100644 --- a/src/SPC/builder/unix/library/pkgconfig.php +++ b/src/SPC/builder/unix/library/pkgconfig.php @@ -13,13 +13,9 @@ trait pkgconfig $cflags = PHP_OS_FAMILY !== 'Linux' ? "{$this->builder->arch_c_flags} -Wimplicit-function-declaration -Wno-int-conversion" : ''; $ldflags = !($this instanceof LinuxLibraryBase) || getenv('SPC_LIBC') === 'glibc' ? '' : '--static'; - shell()->cd($this->source_dir) - ->setEnv([ - 'CFLAGS' => "{$this->getLibExtraCFlags()} {$cflags}", - 'LDFLAGS' => "{$this->getLibExtraLdFlags()} {$ldflags}", - 'LIBS' => $this->getLibExtraLibs(), - ]) - ->execWithEnv( + shell()->cd($this->source_dir)->initializeEnv($this) + ->appendEnv(['CFLAGS' => $cflags, 'LDFLAGS' => $ldflags]) + ->exec( './configure ' . '--disable-shared ' . '--enable-static ' . @@ -33,8 +29,8 @@ trait pkgconfig '--without-pc-path' ) ->exec('make clean') - ->execWithEnv("make -j{$this->builder->concurrency}") - ->execWithEnv('make install-exec'); + ->exec("make -j{$this->builder->concurrency}") + ->exec('make install-exec'); shell()->exec('strip ' . BUILD_ROOT_PATH . '/bin/pkg-config'); } } diff --git a/src/SPC/builder/unix/library/readline.php b/src/SPC/builder/unix/library/readline.php index 0e881e7c..c0fe9078 100644 --- a/src/SPC/builder/unix/library/readline.php +++ b/src/SPC/builder/unix/library/readline.php @@ -15,13 +15,8 @@ trait readline */ protected function build(): void { - shell()->cd($this->source_dir) - ->setEnv([ - 'CFLAGS' => $this->getLibExtraCFlags(), - 'LDFLAGS' => $this->getLibExtraLdFlags(), - 'LIBS' => $this->getLibExtraLibs(), - ]) - ->execWithEnv( + shell()->cd($this->source_dir)->initializeEnv($this) + ->exec( './configure ' . '--enable-static=yes ' . '--enable-shared=no ' . @@ -29,9 +24,9 @@ trait readline '--with-curses ' . '--enable-multibyte=yes' ) - ->execWithEnv('make clean') - ->execWithEnv("make -j{$this->builder->concurrency}") - ->execWithEnv('make install DESTDIR=' . BUILD_ROOT_PATH); + ->exec('make clean') + ->exec("make -j{$this->builder->concurrency}") + ->exec('make install DESTDIR=' . BUILD_ROOT_PATH); $this->patchPkgconfPrefix(['readline.pc']); } } diff --git a/src/SPC/builder/unix/library/snappy.php b/src/SPC/builder/unix/library/snappy.php index e1a1d415..d2bce8fc 100644 --- a/src/SPC/builder/unix/library/snappy.php +++ b/src/SPC/builder/unix/library/snappy.php @@ -6,7 +6,7 @@ namespace SPC\builder\unix\library; use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; -use SPC\store\FileSystem; +use SPC\util\executor\UnixCMakeExecutor; trait snappy { @@ -16,16 +16,12 @@ trait snappy */ protected function build(): void { - FileSystem::resetDir($this->source_dir . '/cmake/build'); - - shell()->cd($this->source_dir . '/cmake/build') - ->exec( - "cmake {$this->builder->makeCmakeArgs()} " . - '-DSNAPPY_BUILD_TESTS=OFF ' . - '-DSNAPPY_BUILD_BENCHMARKS=OFF ' . - '../..' + UnixCMakeExecutor::create($this) + ->setBuildDir("{$this->source_dir}/cmake/build") + ->addConfigureArgs( + '-DSNAPPY_BUILD_TESTS=OFF', + '-DSNAPPY_BUILD_BENCHMARKS=OFF', ) - ->exec("cmake --build . -j {$this->builder->concurrency}") - ->exec('make install'); + ->build('../..'); } } diff --git a/src/SPC/builder/unix/library/sqlite.php b/src/SPC/builder/unix/library/sqlite.php index 131e0c3b..ca21cc9d 100644 --- a/src/SPC/builder/unix/library/sqlite.php +++ b/src/SPC/builder/unix/library/sqlite.php @@ -8,16 +8,11 @@ trait sqlite { protected function build(): void { - shell()->cd($this->source_dir) - ->setEnv([ - 'CFLAGS' => $this->getLibExtraCFlags(), - 'LDFLAGS' => $this->getLibExtraLdFlags(), - 'LIBS' => $this->getLibExtraLibs(), - ]) - ->execWithEnv('./configure --enable-static --disable-shared --with-pic --prefix=') - ->execWithEnv('make clean') - ->execWithEnv("make -j{$this->builder->concurrency}") - ->execWithEnv('make install DESTDIR=' . BUILD_ROOT_PATH); + shell()->cd($this->source_dir)->initializeEnv($this) + ->exec('./configure --enable-static --disable-shared --with-pic --prefix=') + ->exec('make clean') + ->exec("make -j{$this->builder->concurrency}") + ->exec('make install DESTDIR=' . BUILD_ROOT_PATH); $this->patchPkgconfPrefix(['sqlite3.pc']); } } diff --git a/src/SPC/builder/unix/library/tidy.php b/src/SPC/builder/unix/library/tidy.php index 18040c92..d842dc6d 100644 --- a/src/SPC/builder/unix/library/tidy.php +++ b/src/SPC/builder/unix/library/tidy.php @@ -6,7 +6,7 @@ namespace SPC\builder\unix\library; use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; -use SPC\store\FileSystem; +use SPC\util\executor\UnixCMakeExecutor; trait tidy { @@ -16,15 +16,13 @@ trait tidy */ protected function build(): void { - $extra = ''; - if (version_compare(get_cmake_version(), '4.0.0', '>=')) { - $extra .= '-DCMAKE_POLICY_VERSION_MINIMUM=3.5'; - } - FileSystem::resetDir($this->source_dir . '/build-dir'); - shell()->cd($this->source_dir . '/build-dir') - ->exec("cmake {$this->builder->makeCmakeArgs()} {$extra} -DBUILD_SHARED_LIB=OFF -DSUPPORT_CONSOLE_APP=OFF ..") - ->exec("cmake --build . -j {$this->builder->concurrency}") - ->exec('make install'); + UnixCMakeExecutor::create($this) + ->setBuildDir("{$this->source_dir}/build-dir") + ->addConfigureArgs( + '-DSUPPORT_CONSOLE_APP=OFF', + '-DBUILD_SHARED_LIB=OFF' + ) + ->build(); $this->patchPkgconfPrefix(['tidy.pc']); } } diff --git a/src/SPC/builder/unix/library/zlib.php b/src/SPC/builder/unix/library/zlib.php index 42c46259..cd5dab48 100644 --- a/src/SPC/builder/unix/library/zlib.php +++ b/src/SPC/builder/unix/library/zlib.php @@ -15,18 +15,11 @@ trait zlib */ protected function build(): void { - [,,$destdir] = SEPARATED_PATH; - - shell()->cd($this->source_dir) - ->setEnv([ - 'CFLAGS' => $this->getLibExtraCFlags(), - 'LDFLAGS' => $this->getLibExtraLdFlags(), - 'LIBS' => $this->getLibExtraLibs(), - ]) - ->execWithEnv('./configure --static --prefix=') - ->execWithEnv('make clean') - ->execWithEnv("make -j{$this->builder->concurrency}") - ->execWithEnv("make install DESTDIR={$destdir}"); + shell()->cd($this->source_dir)->initializeEnv($this) + ->exec('./configure --static --prefix=') + ->exec('make clean') + ->exec("make -j{$this->builder->concurrency}") + ->exec('make install DESTDIR=' . BUILD_ROOT_PATH); $this->patchPkgconfPrefix(['zlib.pc']); } } diff --git a/src/SPC/builder/unix/library/zstd.php b/src/SPC/builder/unix/library/zstd.php index 6e2b67e4..4bb99c7e 100644 --- a/src/SPC/builder/unix/library/zstd.php +++ b/src/SPC/builder/unix/library/zstd.php @@ -6,7 +6,7 @@ namespace SPC\builder\unix\library; use SPC\exception\FileSystemException; use SPC\exception\RuntimeException; -use SPC\store\FileSystem; +use SPC\util\executor\UnixCMakeExecutor; trait zstd { @@ -16,21 +16,13 @@ trait zstd */ protected function build(): void { - FileSystem::resetDir($this->source_dir . '/build/cmake/build'); - shell()->cd($this->source_dir . '/build/cmake/build') - ->setEnv([ - 'CFLAGS' => $this->getLibExtraCFlags(), - 'LDFLAGS' => $this->getLibExtraLdFlags(), - 'LIBS' => $this->getLibExtraLibs(), - ]) - ->execWithEnv( - "cmake {$this->builder->makeCmakeArgs()} " . - '-DZSTD_BUILD_STATIC=ON ' . - '-DZSTD_BUILD_SHARED=OFF ' . - '..' + UnixCMakeExecutor::create($this) + ->setBuildDir("{$this->source_dir}/build/cmake/build") + ->addConfigureArgs( + '-DZSTD_BUILD_STATIC=ON', + '-DZSTD_BUILD_SHARED=OFF', ) - ->execWithEnv("cmake --build . -j {$this->builder->concurrency}") - ->execWithEnv('make install'); + ->build(); $this->patchPkgconfPrefix(['libzstd.pc']); } } diff --git a/src/SPC/util/UnixShell.php b/src/SPC/util/UnixShell.php index f8a80aff..e31d6410 100644 --- a/src/SPC/util/UnixShell.php +++ b/src/SPC/util/UnixShell.php @@ -4,6 +4,9 @@ declare(strict_types=1); namespace SPC\util; +use SPC\builder\freebsd\library\BSDLibraryBase; +use SPC\builder\linux\library\LinuxLibraryBase; +use SPC\builder\macos\library\MacOSLibraryBase; use SPC\exception\RuntimeException; use ZM\Logger\ConsoleColor; @@ -42,6 +45,10 @@ class UnixShell /* @phpstan-ignore-next-line */ logger()->info(ConsoleColor::yellow('[EXEC] ') . ConsoleColor::green($cmd)); logger()->debug('Executed at: ' . debug_backtrace()[0]['file'] . ':' . debug_backtrace()[0]['line']); + $env_str = $this->getEnvString(); + if (!empty($env_str)) { + $cmd = "{$env_str} {$cmd}"; + } if ($this->cd !== null) { $cmd = 'cd ' . escapeshellarg($this->cd) . ' && ' . $cmd; } @@ -52,6 +59,37 @@ class UnixShell return $this; } + /** + * Init the environment variable that common build will be used. + * + * @param BSDLibraryBase|LinuxLibraryBase|MacOSLibraryBase $library Library class + */ + public function initializeEnv(BSDLibraryBase|LinuxLibraryBase|MacOSLibraryBase $library): UnixShell + { + $this->setEnv([ + 'CFLAGS' => $library->getLibExtraCFlags(), + 'LDFLAGS' => $library->getLibExtraLdFlags(), + 'LIBS' => $library->getLibExtraLibs(), + 'CXXFLAGS' => $library->getLibExtraCXXFlags(), + ]); + return $this; + } + + public function appendEnv(array $env): UnixShell + { + foreach ($env as $k => $v) { + if ($v === '') { + continue; + } + if (!isset($this->env[$k])) { + $this->env[$k] = $v; + } else { + $this->env[$k] = "{$v} {$this->env[$k]}"; + } + } + return $this; + } + public function execWithResult(string $cmd, bool $with_log = true): array { if ($with_log) { @@ -80,14 +118,6 @@ class UnixShell return $this; } - /** - * @throws RuntimeException - */ - public function execWithEnv(string $cmd): UnixShell - { - return $this->exec($this->getEnvString() . ' ' . $cmd); - } - private function getEnvString(): string { $str = ''; diff --git a/src/SPC/util/executor/Executor.php b/src/SPC/util/executor/Executor.php new file mode 100644 index 00000000..05bb408c --- /dev/null +++ b/src/SPC/util/executor/Executor.php @@ -0,0 +1,20 @@ +initBuildDir(); + + if ($this->reset) { + FileSystem::resetDir($this->build_dir); + } + + // prepare shell + $shell = shell()->cd($this->build_dir)->initializeEnv($this->library); + + // config + $this->steps >= 1 && $shell->exec("cmake {$this->getConfigureArgs()} {$this->getDefaultCMakeArgs()} {$build_pos}"); + + // make + $this->steps >= 2 && $shell->exec("cmake --build . -j {$this->library->getBuilder()->concurrency}"); + + // install + $this->steps >= 3 && $shell->exec('make install'); + } + + /** + * Add optional library configuration. + * This method checks if a library is available and adds the corresponding arguments to the CMake configuration. + * + * @param string $name library name to check + * @param \Closure|string $true_args arguments to use if the library is available (allow closure, returns string) + * @param string $false_args arguments to use if the library is not available + * @return $this + */ + public function optionalLib(string $name, \Closure|string $true_args, string $false_args = ''): static + { + if ($get = $this->library->getBuilder()->getLib($name)) { + $args = $true_args instanceof \Closure ? $true_args($get) : $true_args; + } else { + $args = $false_args; + } + $this->addConfigureArgs($args); + return $this; + } + + /** + * Add configure args. + */ + public function addConfigureArgs(...$args): static + { + $this->configure_args = [...$this->configure_args, ...$args]; + return $this; + } + + /** + * To build steps. + * + * @param int $step Step number, accept 1-3 + * @return $this + */ + public function toStep(int $step): static + { + $this->steps = $step; + return $this; + } + + /** + * Set custom CMake build directory. + * + * @param string $dir custom CMake build directory + */ + public function setBuildDir(string $dir): static + { + $this->build_dir = $dir; + return $this; + } + + /** + * Set the custom default args. + */ + public function setCustomDefaultArgs(...$args): static + { + $this->custom_default_args = $args; + return $this; + } + + /** + * Set the reset status. + * If we set it to false, it will not clean and create the specified cmake working directory. + */ + public function setReset(bool $reset): static + { + $this->reset = $reset; + return $this; + } + + /** + * Get configure argument line. + */ + private function getConfigureArgs(): string + { + return implode(' ', $this->configure_args); + } + + /** + * @throws WrongUsageException + * @throws FileSystemException + */ + private function getDefaultCMakeArgs(): string + { + return implode(' ', $this->custom_default_args ?? [ + '-DCMAKE_BUILD_TYPE=Release', + "-DCMAKE_INSTALL_PREFIX={$this->library->getBuildRootPath()}", + '-DCMAKE_INSTALL_BINDIR=bin', + '-DCMAKE_INSTALL_LIBDIR=lib', + '-DCMAKE_INSTALL_INCLUDEDIR=include', + '-DBUILD_SHARED_LIBS=OFF', + "-DCMAKE_TOOLCHAIN_FILE={$this->makeCmakeToolchainFile()}", + ]); + } + + /** + * Initialize the CMake build directory. + * If the directory is not set, it defaults to the library's source directory with '/build' appended. + */ + private function initBuildDir(): void + { + if ($this->build_dir === null) { + $this->build_dir = "{$this->library->getSourceDir()}/build"; + } + } + + /** + * Generate cmake toolchain file for current spc instance, and return the file path. + * + * @return string CMake toolchain file path + * @throws FileSystemException + * @throws WrongUsageException + */ + private function makeCmakeToolchainFile(): string + { + static $created; + if (isset($created)) { + return $created; + } + $os = PHP_OS_FAMILY; + $target_arch = arch2gnu(php_uname('m')); + $cflags = getenv('SPC_DEFAULT_C_FLAGS'); + $cc = getenv('CC'); + $cxx = getenv('CCX'); + logger()->debug("making cmake tool chain file for {$os} {$target_arch} with CFLAGS='{$cflags}'"); + $root = BUILD_ROOT_PATH; + $ccLine = ''; + if ($cc) { + $ccLine = 'SET(CMAKE_C_COMPILER ' . $cc . ')'; + } + $cxxLine = ''; + if ($cxx) { + $cxxLine = 'SET(CMAKE_CXX_COMPILER ' . $cxx . ')'; + } + $toolchain = <<util = new $util_class(); } - /** - * @throws FileSystemException - */ - public function testMakeCmakeToolchainFile() - { - $str = $this->util->makeCmakeToolchainFile(PHP_OS_FAMILY, 'x86_64', ''); - $this->assertIsString($str); - } - public function testFindCommand() { $this->assertIsString($this->util->findCommand('bash'));