diff --git a/src/Package/Target/php/unix.php b/src/Package/Target/php/unix.php index 8d5845bf2..9bda4dac2 100644 --- a/src/Package/Target/php/unix.php +++ b/src/Package/Target/php/unix.php @@ -143,12 +143,19 @@ public function configureForUnix(TargetPackage $package, PackageInstaller $insta $configure_str = str_replace('--with-pic', '--enable-pic', $configure_str); } + // Configure probes need macOS frameworks, but not static libraries that expose polyfills. + $libs = SystemTarget::getRuntimeLibs(); + if (SystemTarget::getTargetOS() === 'Darwin') { + $frameworks = new SPCConfigUtil()->getFrameworksString(array_keys($installer->getResolvedPackages())); + $libs = trim("{$libs} {$frameworks}"); + } + // run ./configure with args $this->seekPhpSrcLogFileOnException(fn () => shell()->cd($package->getSourceDir())->setEnv([ 'CFLAGS' => getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS'), 'CPPFLAGS' => "-I{$package->getIncludeDir()}", 'LDFLAGS' => "-L{$package->getLibDir()} " . getenv('SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS'), - 'LIBS' => SystemTarget::getRuntimeLibs(), + 'LIBS' => $libs, ])->exec($configure_str), $package->getSourceDir()); } diff --git a/tests/StaticPHP/Package/PhpUnixConfigureTest.php b/tests/StaticPHP/Package/PhpUnixConfigureTest.php new file mode 100644 index 000000000..8c7e893cf --- /dev/null +++ b/tests/StaticPHP/Package/PhpUnixConfigureTest.php @@ -0,0 +1,101 @@ +markTestSkipped('Requires a Unix shell.'); + } + + $output = tempnam(sys_get_temp_dir(), 'spc-configure-libs-'); + $this->assertNotFalse($output); + $property = new \ReflectionProperty(PackageConfig::class, 'package_configs'); + $savedConfig = $property->getValue(); + $env = [ + 'SPC_TARGET' => '', + 'SPC_CMD_PREFIX_PHP_CONFIGURE' => escapeshellarg(PHP_BINARY) . ' -n -r ' . escapeshellarg('file_put_contents(' . var_export($output, true) . ', getenv("LIBS"));') . ' --', + 'SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS' => '', + 'SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS' => '', + 'SPC_EXTRA_PHP_VARS' => '', + 'LIBS' => '-lpgport', + ]; + $savedEnv = []; + foreach ($env as $name => $value) { + $savedEnv[$name] = getenv($name); + putenv("{$name}={$value}"); + } + + try { + $property->setValue(null, [ + 'krb5' => ['type' => 'library', 'frameworks' => ['Kerberos'], 'static-libs' => ['/fixtures/libkrb5.a']], + 'gettext' => ['type' => 'library', 'frameworks' => ['CoreFoundation', 'Kerberos']], + 'postgresql' => ['type' => 'library', 'static-libs' => ['/fixtures/libpgport.a']], + 'unresolved' => ['type' => 'library', 'frameworks' => ['Security']], + ]); + $package = $this->createMock(TargetPackage::class); + $package->method('getSourceDir')->willReturn(__DIR__); + $package->method('getIncludeDir')->willReturn('/fixtures/include'); + $package->method('getLibDir')->willReturn('/fixtures/lib'); + $package->method('getBuildOption')->willReturnCallback(static fn (string $name, mixed $default = null): mixed => $name === 'disable-opcache-jit' ? true : $default); + $installer = $this->createMock(PackageInstaller::class); + $resolved = [ + 'krb5' => $this->createMock(LibraryPackage::class), + 'gettext' => $this->createMock(LibraryPackage::class), + 'postgresql' => $this->createMock(LibraryPackage::class), + ]; + $installer->method('getResolvedPackages')->willReturnCallback(static function () use (&$resolved): array { + return $resolved; + }); + $php = new class { + use unix; + + public static function getPHPVersionID(): int + { + return 80500; + } + + public function makeStaticExtensionString(PackageInstaller $installer): string + { + return ''; + } + }; + + foreach (['x86_64-macos', 'aarch64-macos', 'x86_64-linux'] as $target) { + putenv("SPC_TARGET={$target}"); + $php->configureForUnix($package, $installer); + $expected = SystemTarget::getRuntimeLibs(); + if (str_contains($target, '-macos')) { + $expected .= ' -framework Kerberos -framework CoreFoundation'; + } + $this->assertSame($expected, file_get_contents($output), $target); + } + + putenv('SPC_TARGET=x86_64-macos'); + $resolved = ['postgresql' => $resolved['postgresql']]; + $php->configureForUnix($package, $installer); + $this->assertSame(SystemTarget::getRuntimeLibs(), file_get_contents($output)); + } finally { + unlink($output); + $property->setValue(null, $savedConfig); + foreach ($savedEnv as $name => $value) { + $value === false ? putenv($name) : putenv("{$name}={$value}"); + } + } + } +}