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 b2e246b3..0727e103 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 1470ce50..d8ced3b0 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/libxml2.php b/src/SPC/builder/linux/library/libxml2.php index 6f42d672..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') - ->exec( - 'cmake ' . - '-DCMAKE_BUILD_TYPE=Release ' . - '-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' ' . - '-DCMAKE_INSTALL_LIBDIR=' . BUILD_LIB_PATH . ' ' . - "-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " . - '-DBUILD_SHARED_LIBS=OFF ' . - '-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 ' . - '..' - ) - ->exec("cmake --build . -j {$this->builder->concurrency}") - ->exec('make install'); - - FileSystem::replaceFileStr( - BUILD_LIB_PATH . '/pkgconfig/libxml-2.0.pc', - '-licudata -licui18n -licuuc', - '-licui18n -licuuc -licudata' - ); - } } diff --git a/src/SPC/builder/macos/MacOSBuilder.php b/src/SPC/builder/macos/MacOSBuilder.php index 0baf1e7d..e218407c 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 355785ed..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()} -DBUILD_SHARED_LIBS=OFF -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 c0ed36c0..51fd031e 100644 --- a/src/SPC/builder/macos/library/libxml2.php +++ b/src/SPC/builder/macos/library/libxml2.php @@ -4,44 +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 ' . - // '--debug-find ' . - '-DCMAKE_BUILD_TYPE=Release ' . - '-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' ' . - '-DCMAKE_INSTALL_LIBDIR=' . BUILD_LIB_PATH . ' ' . - "-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " . - '-DBUILD_SHARED_LIBS=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 ' . - '..' - ) - ->exec("cmake --build . -j {$this->builder->concurrency}") - ->exec('make install'); - } } 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 . - '-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/brotli.php b/src/SPC/builder/unix/library/brotli.php index 9e764fcb..7f5f4dbb 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,21 +17,10 @@ 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 . ' ' . - '-DBUILD_SHARED_LIBS=OFF ' . - '..' - ) - ->execWithEnv("cmake --build . -j {$this->builder->concurrency}") - ->execWithEnv('make install'); + UnixCMakeExecutor::create($this) + ->setBuildDir("{$this->getSourceDir()}/build-dir") + ->build(); + $this->patchPkgconfPrefix(['libbrotlicommon.pc', 'libbrotlidec.pc', 'libbrotlienc.pc']); shell()->cd(BUILD_ROOT_PATH . '/lib')->exec('ln -sf libbrotlicommon.a libbrotli.a'); foreach (FileSystem::scanDirFiles(BUILD_ROOT_PATH . '/lib/', false, true) as $filename) { diff --git a/src/SPC/builder/unix/library/curl.php b/src/SPC/builder/unix/library/curl.php index 23b1c80a..ea8b6320 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_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_SHARED_LIBS=OFF -DBUILD_CURL_EXE=OFF -DBUILD_LIBCURL_DOCS=OFF {$extra} ..") - ->execWithEnv("make -j{$this->builder->concurrency}") - ->execWithEnv('make install'); // patch pkgconf $this->patchPkgconfPrefix(['libcurl.pc']); shell()->cd(BUILD_LIB_PATH . '/cmake/CURL/') diff --git a/src/SPC/builder/unix/library/freetype.php b/src/SPC/builder/unix/library/freetype.php index 94998b7c..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,24 +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 " . - '-DBUILD_SHARED_LIBS=OFF ' . - "{$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/gmssl.php b/src/SPC/builder/unix/library/gmssl.php index 1d946621..89fc5207 100644 --- a/src/SPC/builder/unix/library/gmssl.php +++ b/src/SPC/builder/unix/library/gmssl.php @@ -4,25 +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()} -DBUILD_SHARED_LIBS=OFF ..") - ->execWithEnv("cmake --build . -j {$this->builder->concurrency}") - ->execWithEnv('make install'); + UnixCMakeExecutor::create($this)->build(); } } diff --git a/src/SPC/builder/unix/library/libaom.php b/src/SPC/builder/unix/library/libaom.php index 5ecf6704..57129389 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,21 +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 ' . - '-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' ' . - "-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " . - '-DCMAKE_BUILD_TYPE=Release ' . - '-DBUILD_SHARED_LIBS=OFF ' . - '-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_GPU=generic') + ->build(); $this->patchPkgconfPrefix(['aom.pc']); } } diff --git a/src/SPC/builder/unix/library/libavif.php b/src/SPC/builder/unix/library/libavif.php index c2aaafcd..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,14 +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()} -DBUILD_SHARED_LIBS=OFF -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/libde265.php b/src/SPC/builder/unix/library/libde265.php index df02bbb3..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,21 +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 ' . - '-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' ' . - "-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " . - '-DCMAKE_BUILD_TYPE=Release ' . - '-DBUILD_SHARED_LIBS=OFF ' . - '-DENABLE_SDL=OFF ' . // Disable SDL, currently not supported - '..' - ) - ->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 2e80f32e..04c35d18 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,27 +40,16 @@ trait libevent */ protected function build(): void { - [$lib, $include, $destdir] = SEPARATED_PATH; - // 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 ' . - '-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' ' . - "-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " . - '-DCMAKE_BUILD_TYPE=Release ' . - '-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 ' . - '..' + UnixCMakeExecutor::create($this) + ->addConfigureArgs( + '-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'); + ->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 e2d2a486..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,26 +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 ' . - '--preset=release ' . - '-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' ' . - "-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " . - '-DCMAKE_BUILD_TYPE=Release ' . - '-DBUILD_SHARED_LIBS=OFF ' . - '-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/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/librabbitmq.php b/src/SPC/builder/unix/library/librabbitmq.php index 42ef553b..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,20 +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 ' . - '-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' ' . - "-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " . - '-DCMAKE_BUILD_TYPE=Release ' . - '-DBUILD_SHARED_LIBS=OFF ' . - '-DBUILD_STATIC_LIBS=ON ' . - '..' - ) - ->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 9e999ca9..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,24 +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 ' . - '-DCMAKE_BUILD_TYPE=Release ' . - "-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " . - '-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' ' . - '-DCMAKE_INSTALL_LIBDIR=lib ' . - '-DBUILD_SHARED_LIBS=OFF ' . - '-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/libuuid.php b/src/SPC/builder/unix/library/libuuid.php index 65ed02ac..197e0f80 100644 --- a/src/SPC/builder/unix/library/libuuid.php +++ b/src/SPC/builder/unix/library/libuuid.php @@ -5,25 +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 efb78a68..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,19 +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() . ' ' . - '-DBUILD_SHARED_LIBS=OFF ' . - '-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/libyaml.php b/src/SPC/builder/unix/library/libyaml.php index 53962e9b..47ce3fb3 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,29 +24,8 @@ trait libyaml return null; } - /** - * @throws RuntimeException - * @throws FileSystemException - */ protected function build(): void { - [$lib, $include, $destdir] = SEPARATED_PATH; - - FileSystem::resetDir($this->source_dir . '/build'); - shell()->cd($this->source_dir . '/build') - ->exec( - 'cmake ' . - // '--debug-find ' . - '-DCMAKE_BUILD_TYPE=Release ' . - '-DBUILD_TESTING=OFF ' . - '-DBUILD_SHARED_LIBS=OFF ' . - '-DCMAKE_INSTALL_PREFIX=/ ' . - "-DCMAKE_INSTALL_LIBDIR={$lib} " . - "-DCMAKE_INSTALL_INCLUDEDIR={$include} " . - "-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " . - '..' - ) - ->exec("make -j{$this->builder->concurrency}") - ->exec("make install DESTDIR={$destdir}"); + UnixCMakeExecutor::create($this)->addConfigureArgs('-DBUILD_TESTING=OFF')->build(); } } diff --git a/src/SPC/builder/unix/library/libzip.php b/src/SPC/builder/unix/library/libzip.php index 5e2bd0d6..b8d2893f 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,35 +16,21 @@ 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 ' . - '-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' ' . - "-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " . - '-DCMAKE_BUILD_TYPE=Release ' . - '-DENABLE_GNUTLS=OFF ' . - '-DENABLE_MBEDTLS=OFF ' . - '-DBUILD_SHARED_LIBS=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_SHARED_LIBS=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 40790a98..78868856 100644 --- a/src/SPC/builder/unix/library/mimalloc.php +++ b/src/SPC/builder/unix/library/mimalloc.php @@ -4,35 +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 ' . - '-DCMAKE_INSTALL_PREFIX=' . BUILD_ROOT_PATH . ' ' . - "-DCMAKE_TOOLCHAIN_FILE={$this->builder->cmake_toolchain_file} " . - '-DCMAKE_BUILD_TYPE=Release ' . - $args . - '..' - ) - ->execWithEnv("make -j{$this->builder->concurrency}") - ->execWithEnv('make install'); + $cmake->build(); } } diff --git a/src/SPC/builder/unix/library/snappy.php b/src/SPC/builder/unix/library/snappy.php index f1b4c825..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,17 +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/tidy.php b/src/SPC/builder/unix/library/tidy.php index 31c851d1..1d05a060 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,17 +16,10 @@ trait tidy */ protected function build(): void { - FileSystem::resetDir($this->source_dir . '/build-dir'); - shell()->cd($this->source_dir . '/build-dir') - ->exec( - 'cmake ' . - "{$this->builder->makeCmakeArgs()} " . - '-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') + ->build(); $this->patchPkgconfPrefix(['tidy.pc']); } } diff --git a/src/SPC/builder/unix/library/zstd.php b/src/SPC/builder/unix/library/zstd.php index 1990f658..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,17 +16,13 @@ trait zstd */ protected function build(): void { - FileSystem::resetDir($this->source_dir . '/build/cmake/build'); - shell()->cd($this->source_dir . '/build/cmake/build') - ->exec( - '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', ) - ->exec("cmake --build . -j {$this->builder->concurrency}") - ->exec('make install'); + ->build(); $this->patchPkgconfPrefix(['libzstd.pc']); } } 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 environment variables + $env = [ + 'CFLAGS' => $this->library->getLibExtraCFlags(), + 'LDFLAGS' => $this->library->getLibExtraLdFlags(), + 'LIBS' => $this->library->getLibExtraLibs(), + ]; + + // prepare shell + $shell = shell()->cd($this->build_dir)->setEnv($env); + + // config + $this->steps >= 1 && $shell->execWithEnv("cmake {$this->getConfigureArgs()} {$this->getDefaultCMakeArgs()} {$build_pos}"); + + // make + $this->steps >= 2 && $shell->execWithEnv("cmake --build . -j {$this->library->getBuilder()->concurrency}"); + + // install + $this->steps >= 3 && $shell->execWithEnv('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_INCLUDE_DIR=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'));