Add autoconf executor

This commit is contained in:
crazywhalecc 2025-06-09 19:32:31 +08:00 committed by Jerry Ma
parent 684b5d4534
commit 720251458f
34 changed files with 437 additions and 454 deletions

View File

@ -328,6 +328,11 @@ abstract class LibraryBase
return false;
}
public function getBinDir(): string
{
return BUILD_BIN_PATH;
}
public function getIncludeDir(): string
{
return BUILD_INCLUDE_PATH;

View File

@ -6,6 +6,7 @@ namespace SPC\builder\linux\library;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\util\executor\UnixAutoconfExecutor;
class libffi extends LinuxLibraryBase
{
@ -17,24 +18,14 @@ class libffi extends LinuxLibraryBase
*/
public function build(): void
{
[$lib, , $destdir] = SEPARATED_PATH;
$arch = getenv('SPC_ARCH');
shell()->cd($this->source_dir)
->initializeEnv($this)
->exec(
'./configure ' .
'--enable-static ' .
'--disable-shared ' .
'--with-pic ' .
"--host={$arch}-unknown-linux " .
"--target={$arch}-unknown-linux " .
'--prefix= ' .
"--libdir={$lib}"
UnixAutoconfExecutor::create($this)
->configure(
"--host={$arch}-unknown-linux",
"--target={$arch}-unknown-linux",
"--libdir={$this->getLibDir()}"
)
->exec('make clean')
->exec("make -j{$this->builder->concurrency}")
->exec("make install DESTDIR={$destdir}");
->make();
if (is_file(BUILD_ROOT_PATH . '/lib64/libffi.a')) {
copy(BUILD_ROOT_PATH . '/lib64/libffi.a', BUILD_ROOT_PATH . '/lib/libffi.a');

View File

@ -24,6 +24,7 @@ namespace SPC\builder\linux\library;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException;
use SPC\util\executor\UnixAutoconfExecutor;
class libpng extends LinuxLibraryBase
{
@ -36,28 +37,21 @@ class libpng extends LinuxLibraryBase
*/
public function build(): void
{
$optimizations = match (getenv('SPC_ARCH')) {
'x86_64' => '--enable-intel-sse ',
'aarch64' => '--enable-arm-neon ',
default => '',
};
shell()->cd($this->source_dir)->initializeEnv($this)
UnixAutoconfExecutor::create($this)
->exec('chmod +x ./configure')
->exec('chmod +x ./install-sh')
->exec(
'LDFLAGS="-L' . BUILD_LIB_PATH . '" ' .
'./configure ' .
'--disable-shared ' .
'--enable-static ' .
'--with-pic ' .
'--enable-hardware-optimizations ' .
'--with-zlib-prefix="' . BUILD_ROOT_PATH . '" ' .
$optimizations .
'--prefix='
->appendEnv(['LDFLAGS' => "-L{$this->getLibDir()}"])
->configure(
'--enable-hardware-optimizations',
"--with-zlib-prefix={$this->getBuildRootPath()}",
match (getenv('SPC_ARCH')) {
'x86_64' => '--enable-intel-sse',
'aarch64' => '--enable-arm-neon',
default => '',
}
)
->exec('make clean')
->exec("make -j{$this->builder->concurrency} DEFAULT_INCLUDES='-I{$this->source_dir} -I" . BUILD_INCLUDE_PATH . "' LIBS= libpng16.la")
->exec('make install-libLTLIBRARIES install-data-am DESTDIR=' . BUILD_ROOT_PATH);
->make('libpng16.la', 'install-libLTLIBRARIES install-data-am', after_env_vars: ['DEFAULT_INCLUDES' => "-I{$this->source_dir} -I{$this->getIncludeDir()}"]);
$this->patchPkgconfPrefix(['libpng16.pc'], PKGCONF_PATCH_PREFIX);
$this->cleanLaFiles();
}

View File

@ -6,6 +6,7 @@ namespace SPC\builder\macos\library;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\util\executor\UnixAutoconfExecutor;
class libffi extends MacOSLibraryBase
{
@ -17,20 +18,13 @@ class libffi extends MacOSLibraryBase
*/
protected function build(): void
{
[, , $destdir] = SEPARATED_PATH;
$arch = getenv('SPC_ARCH');
shell()->cd($this->source_dir)
->exec(
'./configure ' .
'--enable-static ' .
'--disable-shared ' .
"--host={$arch}-apple-darwin " .
"--target={$arch}-apple-darwin " .
'--prefix= ' // use prefix=/
UnixAutoconfExecutor::create($this)
->configure(
"--host={$arch}-apple-darwin",
"--target={$arch}-apple-darwin",
)
->exec('make clean')
->exec("make -j{$this->builder->concurrency}")
->exec("make install DESTDIR={$destdir}");
->make();
$this->patchPkgconfPrefix(['libffi.pc']);
}
}

View File

@ -4,6 +4,8 @@ declare(strict_types=1);
namespace SPC\builder\macos\library;
use SPC\util\executor\UnixAutoconfExecutor;
/**
* gmp is a template library class for unix
*/
@ -13,19 +15,6 @@ class libmemcached extends MacOSLibraryBase
public function build(): void
{
$rootdir = BUILD_ROOT_PATH;
shell()->cd($this->source_dir)
->exec('chmod +x configure')
->exec(
'./configure ' .
'--enable-static --disable-shared ' .
'--disable-sasl ' .
"--prefix={$rootdir}"
)
->exec('make clean')
->exec('sed -ie "s/-Werror//g" ' . $this->source_dir . '/Makefile')
->exec("make -j{$this->builder->concurrency}")
->exec('make install');
UnixAutoconfExecutor::create($this)->configure('--disable-sasl')->exec("sed -ie 's/-Werror//g' ./Makefile")->make();
}
}

View File

@ -24,6 +24,7 @@ namespace SPC\builder\macos\library;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException;
use SPC\util\executor\UnixAutoconfExecutor;
class libpng extends MacOSLibraryBase
{
@ -36,28 +37,24 @@ class libpng extends MacOSLibraryBase
*/
protected function build(): void
{
$optimizations = match (php_uname('m')) {
'x86_64' => '--enable-intel-sse ',
'arm64' => '--enable-arm-neon ',
default => '',
};
shell()->cd($this->source_dir)
$arch = arch2gnu(php_uname('m'));
UnixAutoconfExecutor::create($this)
->exec('chmod +x ./configure')
->exec('chmod +x ./install-sh')
->exec(
'./configure ' .
'--host=' . arch2gnu(php_uname('m')) . '-apple-darwin ' .
'--disable-shared ' .
'--enable-static ' .
'--enable-hardware-optimizations ' .
$optimizations .
'--prefix='
->appendEnv(['LDFLAGS' => "-L{$this->getLibDir()}"])
->configure(
"--host={$arch}-apple-darwin",
'--enable-hardware-optimizations',
"--with-zlib-prefix={$this->getBuildRootPath()}",
match (getenv('SPC_ARCH')) {
'x86_64' => '--enable-intel-sse',
'aarch64' => '--enable-arm-neon',
default => '',
}
)
->exec('make clean')
->exec("make -j{$this->builder->concurrency} DEFAULT_INCLUDES='-I. -I" . BUILD_INCLUDE_PATH . "' LIBS= libpng16.la")
->exec('make install-libLTLIBRARIES install-data-am DESTDIR=' . BUILD_ROOT_PATH)
->cd(BUILD_LIB_PATH)
->exec('ln -sf libpng16.a libpng.a');
->make('libpng16.la', 'install-libLTLIBRARIES install-data-am', after_env_vars: ['DEFAULT_INCLUDES' => "-I{$this->source_dir} -I{$this->getIncludeDir()}"]);
shell()->cd(BUILD_LIB_PATH)->exec('ln -sf libpng16.a libpng.a');
$this->patchPkgconfPrefix(['libpng16.pc'], PKGCONF_PATCH_PREFIX);
$this->patchLaDependencyPrefix(['libpng16.la']);
$this->cleanLaFiles();

View File

@ -5,6 +5,7 @@ declare(strict_types=1);
namespace SPC\builder\unix\library;
use SPC\exception\RuntimeException;
use SPC\util\executor\UnixAutoconfExecutor;
trait attr
{
@ -13,14 +14,11 @@ trait attr
*/
protected function build(): void
{
shell()->cd($this->source_dir)->initializeEnv($this)
->appendEnv(['CFLAGS' => "-I{$this->getIncludeDir()}", 'LDFLAGS' => "-L{$this->getLibDir()}"])
UnixAutoconfExecutor::create($this)
->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);
->configure('--disable-nls')
->make();
$this->patchPkgconfPrefix(['libattr.pc'], PKGCONF_PATCH_PREFIX);
}
}

View File

@ -4,36 +4,34 @@ declare(strict_types=1);
namespace SPC\builder\unix\library;
use SPC\util\executor\UnixAutoconfExecutor;
trait gettext
{
protected function build(): void
{
$extra = $this->builder->getLib('ncurses') ? ('--with-libncurses-prefix=' . BUILD_ROOT_PATH . ' ') : '';
$extra .= $this->builder->getLib('libxml2') ? ('--with-libxml2-prefix=' . BUILD_ROOT_PATH . ' ') : '';
$autoconf = UnixAutoconfExecutor::create($this)
->optionalLib('ncurses', "--with-libncurses-prefix={$this->getBuildRootPath()}")
->optionalLib('libxml2', "--with-libxml2-prefix={$this->getBuildRootPath()}")
->addConfigureArgs(
'--disable-java',
'--disable-c++',
'--with-included-gettext',
"--with-iconv-prefix={$this->getBuildRootPath()}",
);
$zts = $this->builder->getOption('enable-zts') ? '--enable-threads=isoc+posix ' : '--disable-threads ';
// zts
if ($this->builder->getOption('enable-zts')) {
$autoconf->addConfigureArgs('--enable-threads=isoc+posix')
->appendEnv([
'CFLAGS' => '-lpthread -D_REENTRANT',
'LDFLGAS' => '-lpthread',
]);
} else {
$autoconf->addConfigureArgs('--disable-threads');
}
$cflags = $this->builder->getOption('enable-zts') ? '-lpthread -D_REENTRANT' : '';
$ldflags = $this->builder->getOption('enable-zts') ? '-lpthread' : '';
shell()->cd($this->source_dir)->initializeEnv($this)
->appendEnv(['CFLAGS' => $cflags, 'LDFLAGS' => $ldflags])
->exec(
'./configure ' .
'--enable-static ' .
'--disable-shared ' .
'--enable-pic ' .
'--disable-java ' .
'--disable-c++ ' .
$zts .
$extra .
'--with-included-gettext ' .
'--with-libiconv-prefix=' . BUILD_ROOT_PATH . ' ' .
'--prefix=' . BUILD_ROOT_PATH
)
->exec('make clean')
->exec("make -j{$this->builder->concurrency}")
->exec('make install');
$autoconf->configure()->make(with_clean: true);
$this->patchLaDependencyPrefix(['libintl.la']);
}
}

View File

@ -6,6 +6,7 @@ namespace SPC\builder\unix\library;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\util\executor\UnixAutoconfExecutor;
trait gmp
{
@ -15,11 +16,7 @@ trait gmp
*/
protected function build(): void
{
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);
UnixAutoconfExecutor::create($this)->configure()->make();
$this->patchPkgconfPrefix(['gmp.pc']);
}
}

View File

@ -9,6 +9,7 @@ use SPC\builder\macos\library\MacOSLibraryBase;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\store\FileSystem;
use SPC\util\executor\UnixAutoconfExecutor;
trait imagemagick
{
@ -18,48 +19,39 @@ trait imagemagick
*/
protected function build(): void
{
$openmp = '--enable-openmp';
// TODO: glibc rh 10 toolset's libgomp.a was built without -fPIC so we can't use openmp without depending on libgomp.so
if (getenv('SPC_LIBC') === 'glibc' && str_contains(getenv('CC'), 'devtoolset-10')) {
$openmp = '--disable-openmp';
}
$extra = "--without-jxl --without-x {$openmp} ";
$required_libs = '';
$optional_libs = [
'libzip' => 'zip',
'libjpeg' => 'jpeg',
'libpng' => 'png',
'libwebp' => 'webp',
'libxml2' => 'xml',
'libheif' => 'heic',
'zlib' => 'zlib',
'xz' => 'lzma',
'zstd' => 'zstd',
'freetype' => 'freetype',
'bzip2' => 'bzlib',
];
foreach ($optional_libs as $lib => $option) {
$extra .= $this->builder->getLib($lib) ? "--with-{$option} " : "--without-{$option} ";
if ($this->builder->getLib($lib) instanceof LinuxLibraryBase) {
$required_libs .= ' ' . $this->builder->getLib($lib)->getStaticLibFiles();
}
}
$ac = UnixAutoconfExecutor::create($this)
->optionalLib('libzip', ...ac_with_args('zip'))
->optionalLib('libjpeg', ...ac_with_args('jpeg'))
->optionalLib('libpng', ...ac_with_args('png'))
->optionalLib('libwebp', ...ac_with_args('webp'))
->optionalLib('libxml2', ...ac_with_args('xml'))
->optionalLib('libheif', ...ac_with_args('heic'))
->optionalLib('zlib', ...ac_with_args('zlib'))
->optionalLib('xz', ...ac_with_args('lzma'))
->optionalLib('zstd', ...ac_with_args('zstd'))
->optionalLib('freetype', ...ac_with_args('freetype'))
->optionalLib('bzip2', ...ac_with_args('bzlib'))
->addConfigureArgs(
// TODO: glibc rh 10 toolset's libgomp.a was built without -fPIC so we can't use openmp without depending on libgomp.so
getenv('SPC_LIBC') === 'glibc' && str_contains(getenv('CC'), 'devtoolset-10') ? '--enable-openmp' : '--disable-openmp',
'--without-jxl',
'--without-x',
);
// special: linux musl needs `-static`
$ldflags = ($this instanceof LinuxLibraryBase) && getenv('SPC_LIBC') !== 'glibc' ? ('-static -ldl') : '-ldl';
// libxml iconv patch
$required_libs .= $this instanceof MacOSLibraryBase ? ('-liconv') : '';
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 .
'--prefix='
)
->exec('make clean')
->exec("make -j{$this->builder->concurrency}")
->exec('make install DESTDIR=' . BUILD_ROOT_PATH);
// special: macOS needs -iconv
$libs = $this instanceof MacOSLibraryBase ? '-liconv' : '';
$ac->appendEnv([
'LDFLAGS' => $ldflags,
'LIBS' => $libs,
'PKG_CONFIG' => '$PKG_CONFIG --static',
]);
$ac->configure()->make();
$filelist = [
'ImageMagick.pc',
'ImageMagick-7.Q16HDRI.pc',

View File

@ -5,6 +5,7 @@ declare(strict_types=1);
namespace SPC\builder\unix\library;
use SPC\store\FileSystem;
use SPC\util\executor\UnixAutoconfExecutor;
trait ldap
{
@ -17,34 +18,19 @@ trait ldap
protected function build(): void
{
$alt = '';
// openssl support
$alt .= $this->builder->getLib('openssl') ? '--with-tls=openssl ' : '';
// gmp support
$alt .= $this->builder->getLib('gmp') ? '--with-mp=gmp ' : '';
// libsodium support
$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');
shell()->cd($this->source_dir)->initializeEnv($this)
->appendEnv(['LDFLAGS' => "-L{$this->getLibDir()}"])
->exec(
$this->builder->makeAutoconfFlags(AUTOCONF_CPPFLAGS) .
' ./configure ' .
'--enable-static ' .
'--disable-shared ' .
'--with-pic ' .
'--disable-slapd ' .
'--without-systemd ' .
'--without-cyrus-sasl ' .
$alt .
'--prefix='
UnixAutoconfExecutor::create($this)
->optionalLib('openssl', '--with-tls=openssl')
->optionalLib('gmp', '--with-mp=gmp')
->optionalLib('libsodium', '--with-argon2=libsodium', '--enable-argon2=no')
->addConfigureArgs(
'--disable-slapd',
'--without-systemd',
'--without-cyrus-sasl',
)
->exec('make clean')
// remove tests and doc to prevent compile failed with error: soelim not found
->appendEnv(['LDFLAGS' => "-L{$this->getLibDir()}"])
->configure()
->exec('sed -i -e "s/SUBDIRS= include libraries clients servers tests doc/SUBDIRS= include libraries clients servers/g" Makefile')
->exec("make -j{$this->builder->concurrency}")
->exec('make install DESTDIR=' . BUILD_ROOT_PATH);
->make();
FileSystem::replaceFileLineContainsString(BUILD_LIB_PATH . '/pkgconfig/ldap.pc', 'Libs: -L${libdir} -lldap', 'Libs: -L${libdir} -lldap -llber');
$this->patchPkgconfPrefix(['ldap.pc', 'lber.pc']);

View File

@ -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\UnixAutoconfExecutor;
trait libacl
{
@ -29,14 +30,11 @@ trait libacl
*/
protected function build(): void
{
shell()->cd($this->source_dir)->initializeEnv($this)
->appendEnv(['CFLAGS' => "-I{$this->getIncludeDir()}", 'LDFLAGS' => "-L{$this->getLibDir()}"])
UnixAutoconfExecutor::create($this)
->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);
->configure('--disable-nls', '--disable-tests')
->make();
$this->patchPkgconfPrefix(['libacl.pc'], PKGCONF_PATCH_PREFIX);
}
}

View File

@ -6,6 +6,7 @@ namespace SPC\builder\unix\library;
use SPC\exception\RuntimeException;
use SPC\store\FileSystem;
use SPC\util\executor\UnixAutoconfExecutor;
trait libcares
{
@ -24,11 +25,7 @@ trait libcares
*/
protected function build(): void
{
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);
UnixAutoconfExecutor::create($this)->configure('--disable-tests')->make();
$this->patchPkgconfPrefix(['libcares.pc'], PKGCONF_PATCH_PREFIX);
}
}

View File

@ -4,23 +4,18 @@ declare(strict_types=1);
namespace SPC\builder\unix\library;
use SPC\util\executor\UnixAutoconfExecutor;
trait libiconv
{
protected function build(): void
{
shell()->cd($this->source_dir)->initializeEnv($this)
->exec(
'./configure ' .
'--enable-static ' .
'--disable-shared ' .
'--enable-pic ' .
'--enable-extra-encodings ' .
'--prefix='
UnixAutoconfExecutor::create($this)
->configure(
'--enable-pic',
'--enable-extra-encodings',
)
->exec('make clean')
->exec("make -j{$this->builder->concurrency}")
->exec('make install DESTDIR=' . BUILD_ROOT_PATH);
->make();
$this->patchLaDependencyPrefix(['libiconv.la']);
}
}

View File

@ -6,6 +6,7 @@ namespace SPC\builder\unix\library;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\util\executor\UnixAutoconfExecutor;
trait librdkafka
{
@ -15,25 +16,29 @@ trait librdkafka
*/
protected function build(): void
{
$builddir = BUILD_ROOT_PATH;
$zstd_option = $this->builder->getLib('zstd') ? ("STATIC_LIB_libzstd={$builddir}/lib/libzstd.a ") : '';
shell()->cd($this->source_dir)
->exec(
$zstd_option .
'./configure ' .
'--enable-static --disable-shared --disable-curl --disable-sasl --disable-valgrind --disable-zlib --disable-ssl ' .
($zstd_option == '' ? '--disable-zstd ' : '') .
'--prefix='
UnixAutoconfExecutor::create($this)
->optionalLib(
'zstd',
function ($lib) {
putenv("STATIC_LIB_libzstd={$lib->getLibDir()}/libzstd.a");
return '';
},
'--disable-zstd'
)
->exec('make clean')
->exec("make -j{$this->builder->concurrency}")
->exec("make install DESTDIR={$builddir}");
->configure(
'--disable-curl',
'--disable-sasl',
'--disable-valgrind',
'--disable-zlib',
'--disable-ssl',
)
->make();
$this->patchPkgconfPrefix(['rdkafka.pc', 'rdkafka-static.pc', 'rdkafka++.pc', 'rdkafka++-static.pc']);
// remove dynamic libs
shell()
->exec("rm -rf {$builddir}/lib/*.so.*")
->exec("rm -rf {$builddir}/lib/*.so")
->exec("rm -rf {$builddir}/lib/*.dylib");
->exec("rm -rf {$this->getLibDir()}/*.so.*")
->exec("rm -rf {$this->getLibDir()}/*.so")
->exec("rm -rf {$this->getLibDir()}/*.dylib");
}
}

View File

@ -4,16 +4,13 @@ declare(strict_types=1);
namespace SPC\builder\unix\library;
use SPC\util\executor\UnixAutoconfExecutor;
trait libsodium
{
protected function build(): void
{
shell()->cd($this->source_dir)->initializeEnv($this)
->exec('./configure --with-pic --enable-static --disable-shared --prefix=')
->exec('make clean')
->exec("make -j{$this->builder->concurrency}")
->exec('make install DESTDIR=' . BUILD_ROOT_PATH);
UnixAutoconfExecutor::create($this)->configure()->make();
$this->patchPkgconfPrefix(['libsodium.pc'], PKGCONF_PATCH_PREFIX);
}
}

View File

@ -6,6 +6,7 @@ namespace SPC\builder\unix\library;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\util\executor\UnixAutoconfExecutor;
trait libtiff
{
@ -15,24 +16,26 @@ trait libtiff
*/
protected function build(): void
{
// zlib
$extra_libs = '--enable-zlib --with-zlib-include-dir=' . BUILD_ROOT_PATH . '/include --with-zlib-lib-dir=' . BUILD_ROOT_PATH . '/lib';
// libjpeg
$extra_libs .= ' --enable-jpeg --disable-old-jpeg --disable-jpeg12 --with-jpeg-include-dir=' . BUILD_ROOT_PATH . '/include --with-jpeg-lib-dir=' . BUILD_ROOT_PATH . '/lib';
// 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)->initializeEnv($this)
->exec(
'./configure ' .
'--enable-static --disable-shared --with-pic ' .
"{$extra_libs} " .
'--disable-cxx ' .
'--prefix='
UnixAutoconfExecutor::create($this)
->configure(
// zlib deps
'--enable-zlib',
"--with-zlib-include-dir={$this->getIncludeDir()}",
"--with-zlib-lib-dir={$this->getLibDir()}",
// libjpeg deps
'--enable-jpeg',
'--disable-old-jpeg',
'--disable-jpeg12',
"--with-jpeg-include-dir={$this->getIncludeDir()}",
"--with-jpeg-lib-dir={$this->getLibDir()}",
// We disabled lzma, zstd, webp, libdeflate by default to reduce the size of the binary
'--disable-lzma',
'--disable-zstd',
'--disable-webp',
'--disable-libdeflate',
'--disable-cxx',
)
->exec('make clean')
->exec("make -j{$this->builder->concurrency}")
->exec('make install DESTDIR=' . BUILD_ROOT_PATH);
->make();
$this->patchPkgconfPrefix(['libtiff-4.pc']);
}
}

View File

@ -8,6 +8,7 @@ use SPC\builder\linux\library\LinuxLibraryBase;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException;
use SPC\util\executor\UnixAutoconfExecutor;
trait libxslt
{
@ -18,35 +19,23 @@ trait libxslt
*/
protected function build(): void
{
$required_libs = '';
foreach ($this->getDependencies() as $dep) {
if ($dep instanceof LinuxLibraryBase) {
$required_libs .= ' ' . $dep->getStaticLibFiles();
}
}
shell()->cd($this->source_dir)->initializeEnv($this)
$static_libs = $this instanceof LinuxLibraryBase ? $this->getStaticLibFiles() : '';
$ac = UnixAutoconfExecutor::create($this)
->appendEnv([
'CFLAGS' => "-I{$this->getIncludeDir()}",
'LDFLAGS' => "-L{$this->getLibDir()}",
'LIBS' => "{$required_libs} -lstdc++",
'LIBS' => "{$static_libs} -lstdc++",
])
->exec(
"{$this->builder->getOption('library_path')} " .
"{$this->builder->getOption('ld_library_path')} " .
'./configure ' .
'--enable-static --disable-shared ' .
'--with-pic ' .
'--without-python ' .
'--without-mem-debug ' .
'--without-crypto ' .
'--without-debug ' .
'--without-debugger ' .
'--with-libxml-prefix=' . escapeshellarg(BUILD_ROOT_PATH) . ' ' .
'--prefix='
)
->exec('make clean')
->exec("make -j{$this->builder->concurrency}")
->exec('make install DESTDIR=' . escapeshellarg(BUILD_ROOT_PATH));
->addConfigureArgs(
'--without-python',
'--without-mem-debug',
'--without-crypto',
'--without-debug',
'--without-debugger',
"--with-libxml-prefix={$this->getBuildRootPath()}",
);
$ac->exec("{$this->builder->getOption('library_path')} {$this->builder->getOption('ld_library_path')} ./configure {$ac->getConfigureArgsString()}")->make();
$this->patchPkgconfPrefix(['libexslt.pc']);
$this->patchLaDependencyPrefix(['libxslt.la', 'libexslt.la']);
shell()->cd(BUILD_LIB_PATH)

View File

@ -5,37 +5,33 @@ declare(strict_types=1);
namespace SPC\builder\unix\library;
use SPC\store\FileSystem;
use SPC\util\executor\UnixAutoconfExecutor;
trait ncurses
{
protected function build(): void
{
$filelist = FileSystem::scanDirFiles(BUILD_BIN_PATH, relative: true);
shell()->cd($this->source_dir)->initializeEnv($this)
->exec(
'./configure ' .
'--enable-static ' .
'--disable-shared ' .
'--enable-overwrite ' .
'--with-curses-h ' .
'--enable-pc-files ' .
'--enable-echo ' .
'--disable-widec ' .
'--with-normal ' .
'--with-ticlib ' .
'--without-tests ' .
'--without-dlsym ' .
'--without-debug ' .
'-enable-symlinks ' .
'--bindir=' . BUILD_ROOT_PATH . '/bin ' .
'--includedir=' . BUILD_ROOT_PATH . '/include ' .
'--libdir=' . BUILD_ROOT_PATH . '/lib ' .
'--prefix=' . BUILD_ROOT_PATH
)
->exec('make clean')
->exec("make -j{$this->builder->concurrency}")
->exec('make install');
UnixAutoconfExecutor::create($this)
->configure(
'--enable-overwrite',
'--with-curses-h',
'--enable-c-files',
'--enable-echo',
'--disable-widec',
'--with-normal',
'--with-ticlib',
'--without-tests',
'--without-dlsym',
'--without-debug',
'-enable-symlinks',
"--bindir={$this->getBinDir()}",
"--includedir={$this->getIncludeDir()}",
"--libdir={$this->getLibDir()}",
"--prefix={$this->getBuildRootPath()}",
)
->make();
$final = FileSystem::scanDirFiles(BUILD_BIN_PATH, relative: true);
// Remove the new files
$new_files = array_diff($final, $filelist);

View File

@ -7,6 +7,7 @@ namespace SPC\builder\unix\library;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException;
use SPC\util\executor\UnixAutoconfExecutor;
trait nghttp2
{
@ -17,42 +18,32 @@ trait nghttp2
*/
protected function build(): void
{
$args = $this->builder->makeAutoconfArgs(static::NAME, [
'zlib' => null,
'openssl' => null,
'libxml2' => null,
'libev' => null,
'libcares' => null,
'libngtcp2' => null,
'libnghttp3' => null,
'libbpf' => null,
'libevent-openssl' => null,
'jansson' => null,
'jemalloc' => null,
'systemd' => null,
]);
if ($brotli = $this->builder->getLib('brotli')) {
/* @phpstan-ignore-next-line */
$args .= ' --with-libbrotlidec=yes LIBBROTLIDEC_CFLAGS="-I' . BUILD_ROOT_PATH . '/include" LIBBROTLIDEC_LIBS="' . $brotli->getStaticLibFiles() . '"';
/* @phpstan-ignore-next-line */
$args .= ' --with-libbrotlienc=yes LIBBROTLIENC_CFLAGS="-I' . BUILD_ROOT_PATH . '/include" LIBBROTLIENC_LIBS="' . $brotli->getStaticLibFiles() . '"';
}
[,,$destdir] = SEPARATED_PATH;
shell()->cd($this->source_dir)->initializeEnv($this)
->exec(
'./configure ' .
'--enable-static ' .
'--disable-shared ' .
'--with-pic ' .
'--enable-lib-only ' .
$args . ' ' .
'--prefix='
UnixAutoconfExecutor::create($this)
->optionalLib('zlib', ...ac_with_args('zlib', true))
->optionalLib('openssl', ...ac_with_args('openssl', true))
->optionalLib('libxml2', ...ac_with_args('libxml2', true))
->optionalLib('libev', ...ac_with_args('libev', true))
->optionalLib('libcares', ...ac_with_args('libcares', true))
->optionalLib('ngtcp2', ...ac_with_args('libngtcp2', true))
->optionalLib('nghttp3', ...ac_with_args('libnghttp3', true))
// ->optionalLib('libbpf', ...ac_with_args('libbpf', true))
// ->optionalLib('libevent-openssl', ...ac_with_args('libevent-openssl', true))
// ->optionalLib('jansson', ...ac_with_args('jansson', true))
// ->optionalLib('jemalloc', ...ac_with_args('jemalloc', true))
// ->optionalLib('systemd', ...ac_with_args('systemd', true))
->optionalLib(
'brotli',
fn ($lib) => implode(' ', [
'--with-brotlidec=yes',
"LIBBROTLIDEC_CFLAGS=\"-I{$lib->getIncludeDir()}\"",
"LIBBROTLIDEC_LIBS=\"{$lib->getStaticLibFiles()}\"",
'--with-libbrotlienc=yes',
"LIBBROTLIENC_CFLAGS=\"-I{$lib->getIncludeDir()}\"",
"LIBBROTLIENC_LIBS=\"{$lib->getStaticLibFiles()}\"",
])
)
->exec('make clean')
->exec("make -j{$this->builder->concurrency}")
->exec("make install DESTDIR={$destdir}");
->configure('--enable-lib-only')
->make();
$this->patchPkgconfPrefix(['libnghttp2.pc']);
$this->patchLaDependencyPrefix(['libnghttp2.la']);
}

View File

@ -6,6 +6,7 @@ namespace SPC\builder\unix\library;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\util\executor\UnixAutoconfExecutor;
trait nghttp3
{
@ -15,18 +16,7 @@ trait nghttp3
*/
protected function build(): void
{
shell()->cd($this->source_dir)->initializeEnv($this)
->exec(
'./configure ' .
'--enable-static ' .
'--disable-shared ' .
'--with-pic ' .
'--enable-lib-only ' .
'--prefix='
)
->exec('make clean')
->exec("make -j{$this->builder->concurrency}")
->exec('make install DESTDIR=' . BUILD_ROOT_PATH);
UnixAutoconfExecutor::create($this)->configure('--enable-lib-only')->make();
$this->patchPkgconfPrefix(['libnghttp3.pc']);
$this->patchLaDependencyPrefix(['libnghttp3.la']);
}

View File

@ -7,6 +7,7 @@ namespace SPC\builder\unix\library;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\exception\WrongUsageException;
use SPC\util\executor\UnixAutoconfExecutor;
trait ngtcp2
{
@ -17,32 +18,24 @@ trait ngtcp2
*/
protected function build(): void
{
$args = $this->builder->makeAutoconfArgs(static::NAME, [
'openssl' => null,
'libev' => null,
'jemalloc' => null,
'libnghttp3' => null,
]);
if ($brotli = $this->builder->getLib('brotli')) {
/* @phpstan-ignore-next-line */
$args .= ' --with-libbrotlidec=yes LIBBROTLIDEC_CFLAGS="-I' . BUILD_ROOT_PATH . '/include" LIBBROTLIDEC_LIBS="' . $brotli->getStaticLibFiles() . '"';
/* @phpstan-ignore-next-line */
$args .= ' --with-libbrotlienc=yes LIBBROTLIENC_CFLAGS="-I' . BUILD_ROOT_PATH . '/include" LIBBROTLIENC_LIBS="' . $brotli->getStaticLibFiles() . '"';
}
shell()->cd($this->source_dir)->initializeEnv($this)
->exec(
'./configure ' .
'--enable-static ' .
'--disable-shared ' .
'--with-pic ' .
'--enable-lib-only ' .
$args . ' ' .
'--prefix='
UnixAutoconfExecutor::create($this)
->optionalLib('openssl', ...ac_with_args('openssl', true))
->optionalLib('libev', ...ac_with_args('libev', true))
->optionalLib('nghttp3', ...ac_with_args('libnghttp3', true))
->optionalLib('jemalloc', ...ac_with_args('jemalloc', true))
->optionalLib(
'brotli',
fn ($lib) => implode(' ', [
'--with-brotlidec=yes',
"LIBBROTLIDEC_CFLAGS=\"-I{$lib->getIncludeDir()}\"",
"LIBBROTLIDEC_LIBS=\"{$lib->getStaticLibFiles()}\"",
'--with-libbrotlienc=yes',
"LIBBROTLIENC_CFLAGS=\"-I{$lib->getIncludeDir()}\"",
"LIBBROTLIENC_LIBS=\"{$lib->getStaticLibFiles()}\"",
])
)
->exec('make clean')
->exec("make -j{$this->builder->concurrency}")
->exec('make install DESTDIR=' . BUILD_ROOT_PATH);
->configure('--enable-lib-only')
->make();
$this->patchPkgconfPrefix(['libngtcp2.pc', 'libngtcp2_crypto_ossl.pc']);
$this->patchLaDependencyPrefix(['libngtcp2.la', 'libngtcp2_crypto_ossl.la']);

View File

@ -6,6 +6,7 @@ namespace SPC\builder\unix\library;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\util\executor\UnixAutoconfExecutor;
trait onig
{
@ -15,13 +16,7 @@ trait onig
*/
protected function build(): void
{
[,,$destdir] = SEPARATED_PATH;
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}");
UnixAutoconfExecutor::create($this)->configure('--enable-pic')->make();
$this->patchPkgconfPrefix(['oniguruma.pc']);
}
}

View File

@ -5,32 +5,27 @@ declare(strict_types=1);
namespace SPC\builder\unix\library;
use SPC\builder\linux\library\LinuxLibraryBase;
use SPC\util\executor\UnixAutoconfExecutor;
trait pkgconfig
{
protected function build(): void
{
$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)->initializeEnv($this)
->appendEnv(['CFLAGS' => $cflags, 'LDFLAGS' => $ldflags])
->exec(
'./configure ' .
'--disable-shared ' .
'--enable-static ' .
'--with-internal-glib ' .
'--disable-host-tool ' .
'--with-pic ' .
'--prefix=' . BUILD_ROOT_PATH . ' ' .
'--without-sysroot ' .
'--without-system-include-path ' .
'--without-system-library-path ' .
'--without-pc-path'
UnixAutoconfExecutor::create($this)
->appendEnv([
'CFLAGS' => PHP_OS_FAMILY !== 'Linux' ? '-Wimplicit-function-declaration -Wno-int-conversion' : '',
'LDFLAGS' => !($this instanceof LinuxLibraryBase) || getenv('SPC_LIBC') === 'glibc' ? '' : '--static',
])
->configure(
'--with-internal-glib',
'--disable-host-tool',
'--without-sysroot',
'--without-system-include-path',
'--without-system-library-path',
'--without-pc-path',
)
->exec('make clean')
->exec("make -j{$this->builder->concurrency}")
->exec('make install-exec');
->make(with_install: 'install-exec');
shell()->exec('strip ' . BUILD_ROOT_PATH . '/bin/pkg-config');
}
}

View File

@ -80,13 +80,9 @@ trait postgresql
throw new RuntimeException('Unsupported version for postgresql: ' . $version . ' !');
}
$env = [
'CFLAGS' => $this->getLibExtraCFlags() . ' ' . $cflags,
'LDFLAGS' => $this->getLibExtraLdFlags(),
'LIBS' => $this->getLibExtraLibs(),
];
// configure
shell()->cd($this->source_dir . '/build')->initializeEnv($this)
->appendEnv(['CFLAGS' => $cflags])
->exec(
"{$envs} ../configure " .
"--prefix={$builddir} " .

View File

@ -8,6 +8,7 @@ use SPC\builder\macos\library\MacOSLibraryBase;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\store\FileSystem;
use SPC\util\executor\UnixAutoconfExecutor;
trait qdbm
{
@ -17,17 +18,9 @@ trait qdbm
*/
protected function build(): void
{
shell()->cd($this->source_dir)
->exec(
'./configure ' .
'--enable-static --disable-shared ' .
'--prefix='
)
->exec('make clean');
$ac = UnixAutoconfExecutor::create($this)->configure();
FileSystem::replaceFileRegex($this->source_dir . '/Makefile', '/MYLIBS = libqdbm.a.*/m', 'MYLIBS = libqdbm.a');
shell()->cd($this->source_dir)
->exec("make -j{$this->builder->concurrency}" . ($this instanceof MacOSLibraryBase ? ' mac' : ''))
->exec('make install DESTDIR=' . BUILD_ROOT_PATH);
$ac->make($this instanceof MacOSLibraryBase ? 'mac' : '');
$this->patchPkgconfPrefix(['qdbm.pc']);
}
}

View File

@ -6,6 +6,7 @@ namespace SPC\builder\unix\library;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\util\executor\UnixAutoconfExecutor;
trait readline
{
@ -15,18 +16,12 @@ trait readline
*/
protected function build(): void
{
shell()->cd($this->source_dir)->initializeEnv($this)
->exec(
'./configure ' .
'--enable-static=yes ' .
'--enable-shared=no ' .
'--prefix= ' .
'--with-curses ' .
'--enable-multibyte=yes'
UnixAutoconfExecutor::create($this)
->configure(
'--with-curses',
'--enable-multibyte=yes',
)
->exec('make clean')
->exec("make -j{$this->builder->concurrency}")
->exec('make install DESTDIR=' . BUILD_ROOT_PATH);
->make();
$this->patchPkgconfPrefix(['readline.pc']);
}
}

View File

@ -4,15 +4,13 @@ declare(strict_types=1);
namespace SPC\builder\unix\library;
use SPC\util\executor\UnixAutoconfExecutor;
trait sqlite
{
protected function build(): void
{
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);
UnixAutoconfExecutor::create($this)->configure()->make();
$this->patchPkgconfPrefix(['sqlite3.pc']);
}
}

View File

@ -6,6 +6,7 @@ namespace SPC\builder\unix\library;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\util\executor\UnixAutoconfExecutor;
trait unixodbc
{
@ -15,21 +16,15 @@ trait unixodbc
*/
protected function build(): void
{
shell()->cd($this->source_dir)->initializeEnv($this)
->exec(
'./configure ' .
'--enable-static --disable-shared ' .
'--disable-debug ' .
'--with-pic ' .
'--disable-dependency-tracking ' .
'--with-libiconv-prefix=' . BUILD_ROOT_PATH . ' ' .
'--with-included-ltdl ' .
'--enable-gui=no ' .
'--prefix='
UnixAutoconfExecutor::create($this)
->configure(
'--disable-debug',
'--disable-dependency-tracking',
"--with-libiconv-prefix={$this->getBuildRootPath()}",
'--with-included-ltdl',
'--enable-gui=no',
)
->exec('make clean')
->exec("make -j{$this->builder->concurrency}")
->exec('make install DESTDIR=' . BUILD_ROOT_PATH);
->make();
$this->patchPkgconfPrefix(['odbc.pc', 'odbccr.pc', 'odbcinst.pc']);
$this->cleanLaFiles();
}

View File

@ -6,6 +6,7 @@ namespace SPC\builder\unix\library;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\util\executor\UnixAutoconfExecutor;
trait xz
{
@ -15,20 +16,14 @@ trait xz
*/
public function build(): void
{
shell()->cd($this->source_dir)->initializeEnv($this)
->exec(
'./configure ' .
'--enable-static ' .
'--disable-shared ' .
'--enable-pic ' .
'--disable-scripts ' .
'--disable-doc ' .
'--with-libiconv ' .
'--prefix='
UnixAutoconfExecutor::create($this)
->configure(
'--enable-pic',
'--disable-scripts',
'--disable-doc',
'--with-libiconv',
)
->exec('make clean')
->exec("make -j{$this->builder->concurrency}")
->exec('make install DESTDIR=' . BUILD_ROOT_PATH);
->make();
$this->patchPkgconfPrefix(['liblzma.pc']);
$this->patchLaDependencyPrefix(['liblzma.la']);
}

View File

@ -6,6 +6,7 @@ namespace SPC\builder\unix\library;
use SPC\exception\FileSystemException;
use SPC\exception\RuntimeException;
use SPC\util\executor\UnixAutoconfExecutor;
trait zlib
{
@ -15,11 +16,7 @@ trait zlib
*/
protected function build(): void
{
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);
UnixAutoconfExecutor::create($this)->configure('--static')->make();
$this->patchPkgconfPrefix(['zlib.pc']);
}
}

View File

@ -118,7 +118,7 @@ class UnixShell
return $this;
}
private function getEnvString(): string
public function getEnvString(): string
{
$str = '';
foreach ($this->env as $k => $v) {

View File

@ -0,0 +1,124 @@
<?php
declare(strict_types=1);
namespace SPC\util\executor;
use SPC\builder\freebsd\library\BSDLibraryBase;
use SPC\builder\linux\library\LinuxLibraryBase;
use SPC\builder\macos\library\MacOSLibraryBase;
use SPC\exception\RuntimeException;
use SPC\util\UnixShell;
class UnixAutoconfExecutor extends Executor
{
protected ?UnixShell $shell = null;
protected array $configure_args = [];
public function __construct(protected BSDLibraryBase|LinuxLibraryBase|MacOSLibraryBase $library)
{
parent::__construct($library);
$this->initShell();
}
/**
* Run ./configure
*/
public function configure(...$args): static
{
$configure_args = implode(' ', array_merge($args, $this->getDefaultConfigureArgs(), $this->configure_args));
$this->shell->exec("./configure {$configure_args}");
return $this;
}
public function getConfigureArgsString(): string
{
return implode(' ', array_merge($this->getDefaultConfigureArgs(), $this->configure_args));
}
/**
* Run make
*
* @param string $target Build target
* @throws RuntimeException
*/
public function make(string $target = '', false|string $with_install = 'install', bool $with_clean = true, array $after_env_vars = []): static
{
if ($with_clean) {
$this->shell->exec('make clean');
}
$after_env_vars_str = $after_env_vars !== [] ? shell()->setEnv($after_env_vars)->getEnvString() : '';
$this->shell->exec("make -j{$this->library->getBuilder()->concurrency} {$target} {$after_env_vars_str}");
if ($with_install !== false) {
$this->shell->exec("make {$with_install}");
}
return $this;
}
public function exec(string $cmd): static
{
$this->shell->exec($cmd);
return $this;
}
/**
* 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;
}
public function appendEnv(array $env): static
{
$this->shell->appendEnv($env);
return $this;
}
/**
* Returns the default autoconf ./configure arguments
*/
private function getDefaultConfigureArgs(): array
{
return [
'--disable-shared',
'--enable-static',
"--prefix={$this->library->getBuildRootPath()}",
'--with-pic',
];
}
/**
* Initialize UnixShell class.
*/
private function initShell(): void
{
$this->shell = shell()->cd($this->library->getSourceDir())->initializeEnv($this->library)->appendEnv([
'CFLAGS' => "-I{$this->library->getIncludeDir()}",
'LDFLAGS' => "-L{$this->library->getLibDir()}",
]);
}
}

View File

@ -216,3 +216,8 @@ function cmake_boolean_args(string $arg_name, bool $negative = false): array
$res = ["-D{$arg_name}=ON", "-D{$arg_name}=OFF"];
return $negative ? array_reverse($res) : $res;
}
function ac_with_args(string $arg_name, bool $use_value = false): array
{
return $use_value ? ["--with-{$arg_name}=yes", "--with-{$arg_name}=no"] : ["--with-{$arg_name}", "--without-{$arg_name}"];
}