Compare commits

...

20 Commits

Author SHA1 Message Date
Jerry Ma
63ab28097f Merge branch 'v3' into v3c/library-fixes 2026-06-16 13:59:12 +08:00
Jerry Ma
0010e35882 ext: add ext-fastchart and ext-fastjson registry entries (#1165) 2026-06-16 13:57:33 +08:00
crazywhalecc
728c8dd598 Make gmssl standalone 2026-06-16 13:19:03 +08:00
Marc
bf6216e59f Merge branch 'v3' into v3c/ext-fastchart-fastjson 2026-06-14 17:14:37 +07:00
Marc
411ad7cc0f Add macports support (#1179) 2026-06-06 21:06:13 +07:00
Kevin Boyd
0761267eb3 Combine the macos tool checks into a single checkBrewOrPorts method 2026-06-04 21:40:01 -07:00
Jerry Ma
80ae7b093c Merge branch 'v3' into v3c/library-fixes 2026-06-04 16:08:37 +08:00
Jerry Ma
072a3b5505 feat: add permissions for id-token and attestations in release build (#1181) 2026-06-04 10:35:38 +08:00
Marc
0e5738b710 toolchain: add SPC_DEFAULT_RANLIB and pin cmake AR/RANLIB (#1163) 2026-06-04 09:25:42 +07:00
crazywhalecc
3ff9426e50 feat: add permissions for id-token and attestations in release build 2026-06-04 09:51:06 +08:00
Kevin Boyd
6057394641 Simplify macports checks 2026-05-31 22:04:44 -07:00
Kevin Boyd
2f4fb9d28f Add a check for macports alongside Brew in toolchainmanager 2026-05-28 22:40:33 -07:00
Kevin Boyd
96ab2de4b1 Add preliminary MacPorts support 2026-05-28 22:38:56 -07:00
henderkes
daea8e10ad fix https://github.com/php/frankenphp/issues/1346 2026-05-28 12:22:14 +07:00
henderkes
727600a73a disable a whole lot of things we don't need to build 2026-05-26 21:10:00 +07:00
crazywhalecc
c641c3b8db Make mongodb standalone 2026-05-25 10:25:47 +08:00
henderkes
29a8c9c196 libraries: honour SPC_DEFAULT_CFLAGS/CXXFLAGS/LDFLAGS and bug fixes
bzip2, fastlz, jbig, qdbm: thread SPC_DEFAULT_CFLAGS into the
hand-rolled Makefile patches and shell compile commands. Backward
compatible when the env var is empty.

icu: append SPC_DEFAULT_CXXFLAGS/LDFLAGS to runConfigureICU's CXXFLAGS
and LDFLAGS so user flags reach the bundled cxx invocation.

openssl: append user CFLAGS/LDFLAGS after the target name on Configure
so options like -flto and -fprofile-* reach the openssl build.

libheif: rewrite libheif 1.22+'s C-incompatible
`struct heif_bad_pixel { uint32_t row; uint32_t column; };` as a
typedef so C consumers compile.

ncurses: filter the clang/zig-cc "N warning(s) generated." stdout line
out of MKlib_gen.sh's preprocessor pipe before sed turns it into
invalid C in lib_gen.c.

libaom: detect target CPU from SystemTarget instead of hard-coding
generic, fall back to generic only when neither nasm nor yasm is
available, and turn off examples/tests/tools/docs.
2026-05-24 21:28:31 +07:00
henderkes
37d8b87c3b oops 2026-05-24 21:11:49 +07:00
henderkes
5172580294 toolchain: add SPC_DEFAULT_RANLIB and pin cmake AR/RANLIB
ClangBrew, ClangNative and GccNative now export SPC_DEFAULT_RANLIB
alongside SPC_DEFAULT_AR. UnixCMakeExecutor honours both when
generating the Linux toolchain file, so cmake uses the toolchain's
ar/ranlib (e.g. zig-ar/zig-ranlib for archives that the system
ranlib does not understand) instead of /usr/bin/ranlib.
2026-05-24 20:55:35 +07:00
henderkes
99e05aa22b ext: add ext-fastchart and ext-fastjson registry entries
Register two iliaal/fastchart and iliaal/fastjson PHP extensions
sourced from ghtar, extracted into php-src/ext/{fastchart,fastjson}.
Both target Linux and Darwin. fastchart depends on freetype and
suggests libpng, libjpeg, libwebp.
2026-05-24 20:55:11 +07:00
44 changed files with 285 additions and 47 deletions

View File

@@ -38,6 +38,9 @@ jobs:
- name: "windows-x64"
os: "ubuntu-latest"
filename: "spc-windows-x64.exe"
permissions:
id-token: write
attestations: write
steps:
- name: "Checkout"
uses: "actions/checkout@v5"
@@ -105,6 +108,12 @@ jobs:
fi
fi
- name: "Generate build provenance attestation"
if: github.event_name != 'pull_request'
uses: actions/attest-build-provenance@v4
with:
subject-path: "${{ github.workspace }}/${{ matrix.operating-system.name == 'windows-x64' && 'spc.exe' || 'spc' }}"
- name: "Copy file"
run: |
if [ "${{ matrix.operating-system.name }}" != "windows-x64" ]; then

View File

@@ -0,0 +1,20 @@
ext-fastchart:
type: php-extension
artifact:
source:
type: ghtar
repo: iliaal/fastchart
extract: php-src/ext/fastchart
prefer-stable: true
metadata:
license-files: [LICENSE]
depends:
- freetype
suggests:
- libpng
- libjpeg
- libwebp
php-extension:
os:
- Linux
- Darwin

View File

@@ -0,0 +1,14 @@
ext-fastjson:
type: php-extension
artifact:
source:
type: ghtar
repo: iliaal/fastjson
extract: php-src/ext/fastjson
prefer-stable: true
metadata:
license-files: [LICENSE]
php-extension:
os:
- Linux
- Darwin

View File

@@ -27,7 +27,10 @@ class brotli
{
UnixCMakeExecutor::create($lib)
->setBuildDir($lib->getSourceDir() . '/build-dir')
->addConfigureArgs("-DSHARE_INSTALL_PREFIX={$lib->getBuildRootPath()}")
->addConfigureArgs(
"-DSHARE_INSTALL_PREFIX={$lib->getBuildRootPath()}",
'-DBROTLI_DISABLE_TESTS=ON',
)
->build();
// Patch pkg-config files

View File

@@ -17,7 +17,9 @@ class bzip2
#[PatchBeforeBuild]
public function patchBeforeBuild(LibraryPackage $lib): void
{
FileSystem::replaceFileStr($lib->getSourceDir() . '/Makefile', 'CFLAGS=-Wall', 'CFLAGS=-fPIC -Wall');
// Makefile pins -O2 -fPIC; inject SPC_DEFAULT_CFLAGS
$extra = deduplicate_flags(trim((string) getenv('SPC_DEFAULT_CFLAGS')) . ' -fPIC -Wall');
FileSystem::replaceFileStr($lib->getSourceDir() . '/Makefile', 'CFLAGS=-Wall', "CFLAGS={$extra}");
}
#[BuildFor('Windows')]

View File

@@ -18,9 +18,11 @@ class fastlz
{
$cc = getenv('CC') ?: 'cc';
$ar = getenv('AR') ?: 'ar';
$extra = trim((string) getenv('SPC_DEFAULT_CFLAGS'));
$extra = $extra !== '' ? $extra . ' -fPIC' : '-O3 -fPIC';
shell()->cd($lib->getSourceDir())->initializeEnv($lib)
->exec("{$cc} -c -O3 -fPIC fastlz.c -o fastlz.o")
->exec("{$cc} -c {$extra} fastlz.c -o fastlz.o")
->exec("{$ar} rcs libfastlz.a fastlz.o");
// Copy header file

View File

@@ -8,6 +8,7 @@ use StaticPHP\Attribute\Package\BuildFor;
use StaticPHP\Attribute\Package\Library;
use StaticPHP\Package\LibraryPackage;
use StaticPHP\Runtime\Executor\UnixAutoconfExecutor;
use StaticPHP\Runtime\SystemTarget;
#[Library('gmp')]
class gmp
@@ -16,10 +17,12 @@ class gmp
#[BuildFor('Darwin')]
public function build(LibraryPackage $lib): void
{
UnixAutoconfExecutor::create($lib)
->appendEnv(['CFLAGS' => '-std=c17'])
->configure('--enable-fat')
->make();
$make = UnixAutoconfExecutor::create($lib)->appendEnv(['CFLAGS' => '-std=c17']);
if (SystemTarget::getTargetArch() === 'x86_64' && SystemTarget::getTargetOS() === 'Linux') {
$libc = SystemTarget::getLibc() === 'glibc' ? 'gnu' : 'musl';
$make->addConfigureArgs(["--host=x86_64-pc-linux-{$libc}"]);
}
$make->configure('--enable-fat')->make();
$lib->patchPkgconfPrefix(['gmp.pc']);
}
}

View File

@@ -24,9 +24,12 @@ class icu
#[BuildFor('Linux')]
public function buildLinux(LibraryPackage $lib, ToolchainInterface $toolchain, PackageBuilder $builder): void
{
// runConfigureICU bakes CXXFLAGS/LDFLAGS, apply user flags too
$userCxxFlags = trim((string) getenv('SPC_DEFAULT_CXXFLAGS'));
$userLdFlags = trim((string) getenv('SPC_DEFAULT_LDFLAGS'));
$cppflags = 'CPPFLAGS="-DU_CHARSET_IS_UTF8=1 -DU_USING_ICU_NAMESPACE=1 -DU_STATIC_IMPLEMENTATION=1 -DPIC -fPIC"';
$cxxflags = 'CXXFLAGS="-std=c++17 -DPIC -fPIC -fno-ident"';
$ldflags = $toolchain->isStatic() ? 'LDFLAGS="-static"' : '';
$cxxflags = "CXXFLAGS=\"-std=c++17 -DPIC -fPIC -fno-ident {$userCxxFlags}\"";
$ldflags = $toolchain->isStatic() ? "LDFLAGS=\"-static {$userLdFlags}\"" : "LDFLAGS=\"{$userLdFlags}\"";
shell()->cd($lib->getSourceDir() . '/source')->initializeEnv($lib)
->exec(
"{$cppflags} {$cxxflags} {$ldflags} " .

View File

@@ -45,6 +45,9 @@ class imagemagick
// implicit --with-gcc-arch
// bleeds host cpu features into built binaries
'--without-gcc-arch',
'--disable-docs',
'--without-utilities',
'--disable-dpc',
);
// special: linux-static target needs `-static`

View File

@@ -17,7 +17,9 @@ class jbig
#[PatchBeforeBuild]
public function patchBeforeBuild(LibraryPackage $lib): void
{
FileSystem::replaceFileStr($lib->getSourceDir() . '/Makefile', 'CFLAGS = -O2 -W -Wno-unused-result', 'CFLAGS = -O2 -W -Wno-unused-result -fPIC');
$extra = trim((string) getenv('SPC_DEFAULT_CFLAGS'));
$cflags = ($extra !== '' ? $extra : '-O2') . ' -W -Wno-unused-result -fPIC';
FileSystem::replaceFileStr($lib->getSourceDir() . '/Makefile', 'CFLAGS = -O2 -W -Wno-unused-result', "CFLAGS = {$cflags}");
}
#[BuildFor('Darwin')]

View File

@@ -35,6 +35,7 @@ class ldap
->optionalPackage('libsodium', '--with-argon2=libsodium', '--enable-argon2=no')
->addConfigureArgs(
'--disable-slapd',
'--disable-debug',
'--without-systemd',
'--without-cyrus-sasl',
'ac_cv_func_pthread_kill_other_threads_np=no'

View File

@@ -9,8 +9,10 @@ use StaticPHP\Attribute\Package\Library;
use StaticPHP\Package\LibraryPackage;
use StaticPHP\Runtime\Executor\UnixCMakeExecutor;
use StaticPHP\Runtime\Executor\WindowsCMakeExecutor;
use StaticPHP\Runtime\SystemTarget;
use StaticPHP\Toolchain\Interface\ToolchainInterface;
use StaticPHP\Toolchain\ZigToolchain;
use StaticPHP\Util\System\UnixUtil;
#[Library('libaom')]
class libaom extends LibraryPackage
@@ -39,9 +41,23 @@ class libaom extends LibraryPackage
$new = trim($extra . ' -D_GNU_SOURCE');
f_putenv("SPC_COMPILER_EXTRA={$new}");
}
$targetCpu = SystemTarget::getTargetArch();
if (str_starts_with($targetCpu, 'aarch')) {
$targetCpu = str_replace('aarch', 'arm', $targetCpu);
}
if (!UnixUtil::findCommand('nasm') && !UnixUtil::findCommand('yasm')) {
$targetCpu = 'generic';
}
UnixCMakeExecutor::create($this)
->setBuildDir("{$this->getSourceDir()}/builddir")
->addConfigureArgs('-DAOM_TARGET_CPU=generic')
->addConfigureArgs(
"-DAOM_TARGET_CPU={$targetCpu}",
'-DCONFIG_RUNTIME_CPU_DETECT=1',
'-DENABLE_EXAMPLES=OFF',
'-DENABLE_TESTS=OFF',
'-DENABLE_TOOLS=OFF',
'-DENABLE_DOCS=OFF',
)
->build();
f_putenv("SPC_COMPILER_EXTRA={$extra}");
$this->patchPkgconfPrefix(['aom.pc']);

View File

@@ -35,7 +35,12 @@ class libavif
->optionalPackage('libjpeg', '-DAVIF_JPEG=SYSTEM', '-DAVIF_JPEG=OFF')
->optionalPackage('libxml2', '-DAVIF_LIBXML2=SYSTEM', '-DAVIF_LIBXML2=OFF')
->optionalPackage('libpng', '-DAVIF_LIBPNG=SYSTEM', '-DAVIF_LIBPNG=OFF')
->addConfigureArgs('-DAVIF_LIBYUV=OFF')
->addConfigureArgs(
'-DAVIF_LIBYUV=OFF',
'-DAVIF_BUILD_APPS=OFF',
'-DAVIF_BUILD_TESTS=OFF',
'-DAVIF_GTEST=OFF',
)
->build();
// patch pkgconfig
$lib->patchPkgconfPrefix(['libavif.pc']);
@@ -49,7 +54,7 @@ class libavif
'-DAVIF_BUILD_APPS=OFF',
'-DAVIF_BUILD_TESTS=OFF',
'-DAVIF_LIBYUV=OFF',
'-DAVIF_ENABLE_GTEST=OFF',
'-DAVIF_GTEST=OFF',
)
->build();
}

View File

@@ -16,7 +16,7 @@ class libffi extends LibraryPackage
public function buildLinux(): void
{
UnixAutoconfExecutor::create($this)
->configure()->make();
->configure('--disable-docs')->make();
if (is_file("{$this->getBuildRootPath()}/lib64/libffi.a")) {
copy("{$this->getBuildRootPath()}/lib64/libffi.a", "{$this->getBuildRootPath()}/lib/libffi.a");
@@ -33,6 +33,7 @@ class libffi extends LibraryPackage
->configure(
"--host={$arch}-apple-darwin",
"--target={$arch}-apple-darwin",
'--disable-docs',
)
->make();
$this->patchPkgconfPrefix(['libffi.pc']);

View File

@@ -24,6 +24,17 @@ class libheif
'list(APPEND REQUIRES_PRIVATE "libbrotlidec")' . "\n" . ' list(APPEND REQUIRES_PRIVATE "libbrotlienc")'
);
}
// libheif 1.22+ ships a C-incompatible header: `struct heif_bad_pixel`
$heif_properties = $lib->getSourceDir() . '/libheif/api/libheif/heif_properties.h';
if (file_exists($heif_properties)
&& str_contains(file_get_contents($heif_properties), 'struct heif_bad_pixel { uint32_t row; uint32_t column; };')
) {
FileSystem::replaceFileStr(
$heif_properties,
'struct heif_bad_pixel { uint32_t row; uint32_t column; };',
'typedef struct heif_bad_pixel { uint32_t row; uint32_t column; } heif_bad_pixel;'
);
}
}
#[BuildFor('Darwin')]
@@ -36,6 +47,7 @@ class libheif
'-DWITH_EXAMPLES=OFF',
'-DWITH_GDK_PIXBUF=OFF',
'-DBUILD_TESTING=OFF',
'-DBUILD_DOCUMENTATION=OFF',
'-DWITH_LIBSHARPYUV=ON', // optional: libwebp
'-DENABLE_PLUGIN_LOADING=OFF',
)

View File

@@ -25,6 +25,7 @@ class libjxl extends LibraryPackage
'-DJPEGXL_ENABLE_MANPAGES=OFF',
'-DJPEGXL_ENABLE_BENCHMARK=OFF',
'-DJPEGXL_ENABLE_PLUGINS=OFF',
'-DJPEGXL_ENABLE_DOXYGEN=OFF',
'-DJPEGXL_ENABLE_SJPEG=ON',
'-DJPEGXL_ENABLE_JNI=OFF',
'-DJPEGXL_ENABLE_TRANSCODE_JPEG=ON',

View File

@@ -12,17 +12,25 @@ use StaticPHP\Runtime\Executor\UnixCMakeExecutor;
#[Library('libmemcached')]
class libmemcached extends LibraryPackage
{
private const array DISABLE_ARGS = [
'-DBUILD_TESTING=OFF',
'-DBUILD_DOCS=OFF',
'-DENABLE_MEMASLAP=OFF',
];
#[BuildFor('Linux')]
public function buildLinux(): void
{
UnixCMakeExecutor::create($this)
->addConfigureArgs('-DCMAKE_INSTALL_RPATH=""')
->addConfigureArgs('-DCMAKE_INSTALL_RPATH=""', ...self::DISABLE_ARGS)
->build();
}
#[BuildFor('Darwin')]
public function buildDarwin(): void
{
UnixCMakeExecutor::create($this)->build();
UnixCMakeExecutor::create($this)
->addConfigureArgs(...self::DISABLE_ARGS)
->build();
}
}

View File

@@ -20,6 +20,8 @@ class libpng
{
$args = [
'--enable-hardware-optimizations',
'--disable-tests',
'--disable-tools',
"--with-zlib-prefix={$lib->getBuildRootPath()}",
];

View File

@@ -13,17 +13,29 @@ use StaticPHP\Runtime\Executor\WindowsCMakeExecutor;
#[Library('librabbitmq')]
class librabbitmq extends LibraryPackage
{
private const array DISABLE_ARGS = [
'-DBUILD_EXAMPLES=OFF',
'-DBUILD_TESTING=OFF',
'-DBUILD_TOOLS=OFF',
'-DBUILD_TOOLS_DOCS=OFF',
'-DBUILD_API_DOCS=OFF',
];
#[BuildFor('Darwin')]
#[BuildFor('Linux')]
public function buildUnix(): void
{
UnixCMakeExecutor::create($this)->addConfigureArgs('-DBUILD_STATIC_LIBS=ON')->build();
UnixCMakeExecutor::create($this)
->addConfigureArgs('-DBUILD_STATIC_LIBS=ON', ...self::DISABLE_ARGS)
->build();
}
#[BuildFor('Windows')]
public function buildWin(): void
{
WindowsCMakeExecutor::create($this)->build();
WindowsCMakeExecutor::create($this)
->addConfigureArgs(...self::DISABLE_ARGS)
->build();
rename("{$this->getLibDir()}\\librabbitmq.4.lib", "{$this->getLibDir()}\\rabbitmq.4.lib");
}
}

View File

@@ -41,6 +41,9 @@ class libtiff
'--disable-libdeflate',
'--disable-tools',
'--disable-contrib',
'--disable-tests',
'--disable-docs',
'--disable-sphinx',
'--disable-cxx',
'--without-x',
)

View File

@@ -13,12 +13,18 @@ use StaticPHP\Runtime\Executor\WindowsCMakeExecutor;
#[Library('libuv')]
class libuv
{
private const array DISABLE_ARGS = [
'-DLIBUV_BUILD_SHARED=OFF',
'-DLIBUV_BUILD_TESTS=OFF',
'-DLIBUV_BUILD_BENCH=OFF',
];
#[BuildFor('Darwin')]
#[BuildFor('Linux')]
public function buildUnix(LibraryPackage $lib): void
{
UnixCMakeExecutor::create($lib)
->addConfigureArgs('-DLIBUV_BUILD_SHARED=OFF')
->addConfigureArgs(...self::DISABLE_ARGS)
->build();
// patch pkgconfig
$lib->patchPkgconfPrefix(['libuv-static.pc']);
@@ -28,7 +34,7 @@ class libuv
public function buildWindows(LibraryPackage $lib): void
{
WindowsCMakeExecutor::create($lib)
->addConfigureArgs('-DLIBUV_BUILD_SHARED=OFF')
->addConfigureArgs(...self::DISABLE_ARGS)
->build();
}
}

View File

@@ -34,6 +34,7 @@ class libxslt
'--without-crypto',
'--without-debug',
'--without-debugger',
'--without-profiler',
"--with-libxml-prefix={$lib->getBuildRootPath()}",
);
if (getenv('SPC_LD_LIBRARY_PATH') && getenv('SPC_LIBRARY_PATH')) {

View File

@@ -21,6 +21,7 @@ class mimalloc
->addConfigureArgs(
'-DMI_BUILD_SHARED=OFF',
'-DMI_BUILD_OBJECT=OFF',
'-DMI_BUILD_TESTS=OFF',
'-DMI_INSTALL_TOPLEVEL=ON',
);
if (SystemTarget::getLibc() === 'musl') {

View File

@@ -6,6 +6,8 @@ namespace Package\Library;
use StaticPHP\Attribute\Package\BuildFor;
use StaticPHP\Attribute\Package\Library;
use StaticPHP\Attribute\Package\PatchBeforeBuild;
use StaticPHP\Attribute\PatchDescription;
use StaticPHP\Package\LibraryPackage;
use StaticPHP\Runtime\Executor\UnixAutoconfExecutor;
use StaticPHP\Toolchain\Interface\ToolchainInterface;
@@ -16,6 +18,24 @@ use StaticPHP\Util\FileSystem;
#[Library('ncursesw')]
class ncurses
{
#[PatchBeforeBuild]
#[PatchDescription('Filter clang/zig "N warning(s) generated." line out of MKlib_gen.sh preprocessor pipe')]
public function patchBeforeBuild(LibraryPackage $lib): void
{
// MKlib_gen.sh feeds the C preprocessor's stdout through a sed/awk
// pipeline into lib_gen.c. zig-cc/clang emits "N warning(s) generated."
// on stdout (not stderr), and that line ends up as invalid C in the
// generated source. Filter it out of the pipe before sed sees it.
$mklibGen = $lib->getSourceDir() . '/ncurses/base/MKlib_gen.sh';
if (is_file($mklibGen) && !str_contains((string) file_get_contents($mklibGen), "| grep -v ' generated")) {
FileSystem::replaceFileStr(
$mklibGen,
'$preprocessor $TMP 2>/dev/null \\',
"\$preprocessor \$TMP 2>/dev/null \\\n| grep -v ' generated\\.\$' \\",
);
}
}
#[BuildFor('Darwin')]
#[BuildFor('Linux')]
public function build(LibraryPackage $package, ToolchainInterface $toolchain): void

View File

@@ -24,6 +24,7 @@ class nghttp3
'-DBUILD_SHARED_LIBS=OFF',
'-DENABLE_STATIC_CRT=ON',
'-DENABLE_LIB_ONLY=ON',
'-DBUILD_TESTING=OFF',
)
->build();
}

View File

@@ -25,6 +25,7 @@ class ngtcp2
'-DENABLE_STATIC_CRT=ON',
'-DENABLE_LIB_ONLY=ON',
'-DENABLE_OPENSSL=OFF',
'-DBUILD_TESTING=OFF',
)
->build();
}

View File

@@ -111,6 +111,12 @@ class openssl
$openssl_dir ??= LinuxUtil::getOSRelease()['dist'] === 'redhat' ? '/etc/pki/tls' : '/etc/ssl';
$ex_lib = trim($ex_lib);
// anything we want included (PGO -fprofile-*, LTO, custom hardening)
// has to be appended on the command line *after* the target name.
$userCFlags = trim((string) getenv('SPC_DEFAULT_CFLAGS'));
$userLdFlags = trim((string) getenv('SPC_DEFAULT_LDFLAGS'));
$userExtra = trim($userCFlags . ' ' . $userLdFlags);
shell()->cd($lib->getSourceDir())->initializeEnv($lib)
->exec(
"{$env} ./Configure no-shared zlib " .
@@ -121,7 +127,8 @@ class openssl
'enable-pie ' .
'no-legacy ' .
'no-tests ' .
"linux-{$arch}"
"linux-{$arch} " .
$userExtra
)
->exec('make clean')
->exec("make -j{$lib->getBuilder()->concurrency} CNF_EX_LIBS=\"{$ex_lib}\"")

View File

@@ -20,6 +20,11 @@ class qdbm
{
$ac = UnixAutoconfExecutor::create($lib)->configure();
FileSystem::replaceFileRegex($lib->getSourceDir() . '/Makefile', '/MYLIBS = libqdbm.a.*/m', 'MYLIBS = libqdbm.a');
// Makefile pins -O3, replace with SPC_DEFAULT_CFLAGS
$extra = trim((string) getenv('SPC_DEFAULT_CFLAGS'));
if ($extra !== '') {
FileSystem::replaceFileRegex($lib->getSourceDir() . '/Makefile', '/^CFLAGS = .*$/m', "CFLAGS = -Wall {$extra}");
}
$ac->make(SystemTarget::getTargetOS() === 'Darwin' ? 'mac' : '');
$lib->patchPkgconfPrefix(['qdbm.pc']);
}

View File

@@ -20,6 +20,7 @@ class readline
->configure(
'--with-curses',
'--enable-multibyte=yes',
'--disable-install-examples',
)
->make();
$lib->patchPkgconfPrefix(['readline.pc']);

View File

@@ -22,7 +22,8 @@ class tidy
->setBuildDir("{$lib->getSourceDir()}/build-dir")
->addConfigureArgs(
'-DSUPPORT_CONSOLE_APP=OFF',
'-DBUILD_SHARED_LIB=OFF'
'-DBUILD_SHARED_LIB=OFF',
'-DSUPPORT_LOCALIZATIONS=OFF',
);
if (version_compare(get_cmake_version(), '4.0.0', '>=')) {
$cmake->addConfigureArgs('-DCMAKE_POLICY_VERSION_MINIMUM=3.5');
@@ -38,7 +39,8 @@ class tidy
->setBuildDir("{$lib->getSourceDir()}/build-dir")
->addConfigureArgs(
'-DSUPPORT_CONSOLE_APP=OFF',
'-DBUILD_SHARED_LIB=OFF'
'-DBUILD_SHARED_LIB=OFF',
'-DSUPPORT_LOCALIZATIONS=OFF',
)->build();
// rename tidy_static.lib to tidy_a.lib

View File

@@ -20,8 +20,8 @@ class unixodbc extends LibraryPackage
{
$sysconf_selector = match ($os = SystemTarget::getTargetOS()) {
'Darwin' => match (SystemTarget::getTargetArch()) {
'x86_64' => '/usr/local/etc',
'aarch64' => '/opt/homebrew/etc',
'x86_64' => is_dir('/usr/local/etc') ? '/usr/local/etc' : '/opt/local/etc',
'aarch64' => is_dir('/opt/homebrew/etc') ? '/opt/homebrew/etc' : '/opt/local/etc',
default => throw new WrongUsageException('Unsupported architecture: ' . GNU_ARCH),
},
'Linux' => '/etc',
@@ -35,6 +35,7 @@ class unixodbc extends LibraryPackage
'--with-included-ltdl',
"--sysconfdir={$sysconf_selector}",
'--enable-gui=no',
'--enable-readline=no',
)
->make();
$this->patchPkgconfPrefix(['odbc.pc', 'odbccr.pc', 'odbcinst.pc']);

View File

@@ -22,6 +22,11 @@ class xz
->configure(
'--disable-scripts',
'--disable-doc',
'--disable-xz',
'--disable-xzdec',
'--disable-lzmadec',
'--disable-lzmainfo',
'--disable-lzma-links',
'--with-libiconv',
'--bindir=/tmp/xz', // xz binary will corrupt `tar` command, that's really strange.
)

View File

@@ -14,16 +14,20 @@ use StaticPHP\Util\FileSystem;
#[Library('zstd')]
class zstd
{
private const array DISABLE_ARGS = [
'-DZSTD_BUILD_STATIC=ON',
'-DZSTD_BUILD_SHARED=OFF',
'-DZSTD_BUILD_PROGRAMS=OFF',
'-DZSTD_BUILD_TESTS=OFF',
];
#[BuildFor('Windows')]
public function buildWin(LibraryPackage $package): void
{
WindowsCMakeExecutor::create($package)
->setWorkingDir("{$package->getSourceDir()}/build/cmake")
->setBuildDir("{$package->getSourceDir()}/build/cmake/build")
->addConfigureArgs(
'-DZSTD_BUILD_STATIC=ON',
'-DZSTD_BUILD_SHARED=OFF',
)
->addConfigureArgs(...self::DISABLE_ARGS)
->build();
FileSystem::copy($package->getLibDir() . '\zstd_static.lib', $package->getLibDir() . '/zstd.lib');
FileSystem::copy($package->getLibDir() . '\zstd_static.lib', $package->getLibDir() . '/libzstd.lib');
@@ -35,10 +39,7 @@ class zstd
{
UnixCMakeExecutor::create($lib)
->setBuildDir("{$lib->getSourceDir()}/build/cmake/build")
->addConfigureArgs(
'-DZSTD_BUILD_STATIC=ON',
'-DZSTD_BUILD_SHARED=OFF',
)
->addConfigureArgs(...self::DISABLE_ARGS)
->build();
$lib->patchPkgconfPrefix(['libzstd.pc'], PKGCONF_PATCH_PREFIX);

View File

@@ -43,6 +43,8 @@ class curl
'-DZSTD_LIBRARY=zstd_static.lib',
'-DBUILD_TESTING=OFF',
'-DBUILD_EXAMPLES=OFF',
'-DBUILD_LIBCURL_DOCS=OFF',
'-DENABLE_CURL_MANUAL=OFF',
'-DUSE_LIBIDN2=OFF',
'-DCURL_USE_LIBPSL=OFF',
'-DUSE_WINDOWS_SSPI=ON',
@@ -81,6 +83,9 @@ class curl
->addConfigureArgs(
'-DBUILD_CURL_EXE=ON',
'-DBUILD_LIBCURL_DOCS=OFF',
'-DBUILD_TESTING=OFF',
'-DBUILD_EXAMPLES=OFF',
'-DENABLE_CURL_MANUAL=OFF',
'-DOPENSSL_ROOT_DIR=' . BUILD_ROOT_PATH,
)
->build();

View File

@@ -60,6 +60,8 @@ class GenExtTestMatrixCommand extends BaseCommand
'glfw',
'imagick',
'intl',
'mongodb',
'gmssl',
];
/**

View File

@@ -33,15 +33,20 @@ class MacOSToolCheck
'glibtoolize',
];
#[CheckItem('if homebrew has installed', limit_os: 'Darwin', level: 998)]
public function checkBrew(): ?CheckResult
#[CheckItem('if homebrew or macports has installed', limit_os: 'Darwin', level: 998)]
public function checkBrewOrPorts(): ?CheckResult
{
if (($path = MacOSUtil::findCommand('brew')) === null) {
return CheckResult::fail('Homebrew is not installed', 'brew');
}
if ($path !== '/opt/homebrew/bin/brew' && getenv('GNU_ARCH') === 'aarch64') {
$brewPath = MacOSUtil::findCommand('brew');
$portPath = MacOSUtil::findCommand('port');
if ($brewPath && $brewPath !== '/opt/homebrew/bin/brew' && getenv('GNU_ARCH') === 'aarch64') {
return CheckResult::fail('Current homebrew (/usr/local/bin/homebrew) is not installed for M1 Mac, please re-install homebrew in /opt/homebrew/ !');
}
if ($brewPath === null && $portPath === null) {
return CheckResult::fail('Homebrew is not installed', 'brew');
}
return CheckResult::ok();
}
@@ -60,8 +65,8 @@ class MacOSToolCheck
return CheckResult::ok();
}
#[CheckItem('if homebrew llvm are installed', limit_os: 'Darwin')]
public function checkBrewLLVM(): ?CheckResult
#[CheckItem('if homebrew or macports llvm are installed', limit_os: 'Darwin')]
public function checkBrewOrPortsLLVM(): ?CheckResult
{
if (getenv('SPC_USE_LLVM') === 'brew') {
$homebrew_prefix = getenv('HOMEBREW_PREFIX') ?: (SystemTarget::getTargetArch() === 'aarch64' ? '/opt/homebrew' : '/usr/local/homebrew');
@@ -71,6 +76,16 @@ class MacOSToolCheck
}
return CheckResult::ok($path);
}
if (getenv('SPC_USE_LLVM') === 'port') {
$macportsPrefix = '/opt/local';
if (($path = MacOSUtil::findCommand('clang', ["{$macportsPrefix}/bin"])) === null) {
return CheckResult::fail('MacPorts llvm is not installed', 'build-tools', ['missing' => ['llvm']]);
}
return CheckResult::ok($path);
}
return null;
}
@@ -91,7 +106,7 @@ class MacOSToolCheck
if ($command_path !== []) {
return CheckResult::fail("Current {$bison} version is too old: " . $matches[0]);
}
return $this->checkBisonVersion(['/opt/homebrew/opt/bison/bin', '/usr/local/opt/bison/bin']);
return $this->checkBisonVersion(['/opt/homebrew/opt/bison/bin', '/usr/local/opt/bison/bin', '/opt/local/bin']);
}
return CheckResult::ok($matches[0]);
}
@@ -108,6 +123,9 @@ class MacOSToolCheck
#[FixItem('build-tools')]
public function fixBuildTools(array $missing): bool
{
$brewPath = MacOSUtil::findCommand('brew');
$portPath = MacOSUtil::findCommand('port');
$replacement = [
'glibtoolize' => 'libtool',
];
@@ -115,7 +133,18 @@ class MacOSToolCheck
if (isset($replacement[$cmd])) {
$cmd = $replacement[$cmd];
}
shell()->exec('brew install --formula ' . escapeshellarg($cmd));
if ($brewPath !== null) {
shell()->exec('brew install --formula ' . escapeshellarg($cmd));
continue;
}
if ($portPath !== null) {
shell()->exec('port install ' . escapeshellarg($cmd));
continue;
}
return false;
}
return true;
}

View File

@@ -302,9 +302,12 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
set(CMAKE_C_STANDARD_INCLUDE_DIRECTORIES "{$include}")
set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES "{$include}")
CMAKE;
// Whoops, linux may need CMAKE_AR sometimes
// pin AR/RANLIB so cmake uses zig-ar/zig-ranlib instead of system /usr/bin/ranlib (zig archives need it)
if (PHP_OS_FAMILY === 'Linux') {
$toolchain .= "\nSET(CMAKE_AR \"ar\")";
$ar = getenv('SPC_DEFAULT_AR') ?: getenv('AR') ?: 'ar';
$ranlib = getenv('SPC_DEFAULT_RANLIB') ?: (getenv('RANLIB') ?: 'ranlib');
$toolchain .= "\nSET(CMAKE_AR \"{$ar}\")";
$toolchain .= "\nSET(CMAKE_RANLIB \"{$ranlib}\")";
}
FileSystem::writeFile(SOURCE_PATH . '/toolchain.cmake', $toolchain);
return $created = realpath(SOURCE_PATH . '/toolchain.cmake');

View File

@@ -15,6 +15,7 @@ class ClangBrewToolchain extends ClangNativeToolchain
GlobalEnvManager::putenv("SPC_DEFAULT_CC={$homebrew_prefix}/opt/llvm/bin/clang");
GlobalEnvManager::putenv("SPC_DEFAULT_CXX={$homebrew_prefix}/opt/llvm/bin/clang++");
GlobalEnvManager::putenv("SPC_DEFAULT_AR={$homebrew_prefix}/opt/llvm/bin/llvm-ar");
GlobalEnvManager::putenv("SPC_DEFAULT_RANLIB={$homebrew_prefix}/opt/llvm/bin/llvm-ranlib");
GlobalEnvManager::putenv('SPC_DEFAULT_LD=ld');
GlobalEnvManager::addPathIfNotExists("{$homebrew_prefix}/opt/llvm/bin");
}

View File

@@ -21,6 +21,7 @@ class ClangNativeToolchain implements UnixToolchainInterface
GlobalEnvManager::putenv('SPC_DEFAULT_CC=clang');
GlobalEnvManager::putenv('SPC_DEFAULT_CXX=clang++');
GlobalEnvManager::putenv('SPC_DEFAULT_AR=ar');
GlobalEnvManager::putenv('SPC_DEFAULT_RANLIB=ranlib');
GlobalEnvManager::putenv('SPC_DEFAULT_LD=ld');
}

View File

@@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
namespace StaticPHP\Toolchain;
use StaticPHP\Util\GlobalEnvManager;
class ClangPortsToolchain extends ClangNativeToolchain
{
public function initEnv(): void
{
$macports_prefix = getenv('MACPORTS_PREFIX') ?: '/opt/local';
GlobalEnvManager::putenv("SPC_DEFAULT_CC={$macports_prefix}/bin/clang");
GlobalEnvManager::putenv("SPC_DEFAULT_CXX={$macports_prefix}/bin/clang++");
GlobalEnvManager::putenv("SPC_DEFAULT_AR={$macports_prefix}/bin/llvm-ar");
GlobalEnvManager::putenv('SPC_DEFAULT_LD=ld');
GlobalEnvManager::addPathIfNotExists("{$macports_prefix}/bin");
}
}

View File

@@ -18,6 +18,7 @@ class GccNativeToolchain implements UnixToolchainInterface
GlobalEnvManager::putenv('SPC_DEFAULT_CC=gcc');
GlobalEnvManager::putenv('SPC_DEFAULT_CXX=g++');
GlobalEnvManager::putenv('SPC_DEFAULT_AR=ar');
GlobalEnvManager::putenv('SPC_DEFAULT_RANLIB=ranlib');
GlobalEnvManager::putenv('SPC_DEFAULT_LD=ld');
}

View File

@@ -41,6 +41,7 @@ class ToolchainManager
'Windows' => MSVCToolchain::class,
'Darwin' => match (getenv('SPC_USE_LLVM') ?: 'system') {
'brew' => ClangBrewToolchain::class,
'port' => ClangPortsToolchain::class,
default => ClangNativeToolchain::class,
},
default => throw new WrongUsageException('Unsupported OS family: ' . PHP_OS_FAMILY),

View File

@@ -16,6 +16,7 @@ class ZigToolchain implements UnixToolchainInterface
GlobalEnvManager::putenv('SPC_DEFAULT_CC=zig-cc');
GlobalEnvManager::putenv('SPC_DEFAULT_CXX=zig-c++');
GlobalEnvManager::putenv('SPC_DEFAULT_AR=zig-ar');
GlobalEnvManager::putenv('SPC_DEFAULT_RANLIB=zig-ranlib');
GlobalEnvManager::putenv('SPC_DEFAULT_LD=zig-ld.lld');
// Generate additional objects needed for zig toolchain

View File

@@ -134,10 +134,10 @@ class GlobalEnvManager
}
// test bison
if (PHP_OS_FAMILY === 'Darwin') {
if ($bison = MacOSUtil::findCommand('bison', ['/opt/homebrew/opt/bison/bin', '/usr/local/opt/bison/bin'])) {
if ($bison = MacOSUtil::findCommand('bison', ['/opt/homebrew/opt/bison/bin', '/usr/local/opt/bison/bin', '/opt/local/bin/bison'])) {
self::putenv("BISON={$bison}");
}
if ($yacc = MacOSUtil::findCommand('yacc', ['/opt/homebrew/opt/bison/bin', '/usr/local/opt/bison/bin'])) {
if ($yacc = MacOSUtil::findCommand('yacc', ['/opt/homebrew/opt/bison/bin', '/usr/local/opt/bison/bin', '/opt/local/bin/yacc'])) {
self::putenv("YACC={$yacc}");
}
}