fix(platform): give Linux the rpaths macOS already gets (#120) --skip-tests

A program built on Linux does not start:

    ./main: error while loading shared libraries: libphpx.so:
    cannot open shared object file: No such file or directory

libphpx.so sits beside the phpx checkout and libphp.so under the prefix the
libphp installer chose. The link line names both with -L, which tells the
linker where to look and the loader nothing, and neither directory is on the
default search path. The binary carries no RPATH or RUNPATH at all, so it
only runs under LD_LIBRARY_PATH.

Every part of the mechanism is already present and already reached on Linux.
NativeCommandOptionsTrait asks the platform for getDefaultRpaths() on every
non-nano build, and GccLikeBackend emits -Wl,-rpath for each entry it gets
back. Only the list is missing: PlatformBase returns an empty one, Macos
overrides it with the phpx and PHP library directories, and Linux never
overrode anything.

Move that override up to UnixPlatform, where Linux inherits it. The two
directories are the same ones the -L flags already name, each still guarded
by is_dir(), so macOS keeps the behavior it has today.

Android and Ios return an empty list on purpose: a path on the build host
means nothing on the device that runs the output. Wasi is a cross target too
and had been relying on the inherited default, so it states the same thing
explicitly rather than acquiring host paths from this move.

The recorded paths are absolute, matching what macOS has always emitted. That
is enough to run where the program was built, which is what an embed build
against a private PHP prefix can do in any case. Relocatable output needs
$ORIGIN and the libraries shipped alongside, or --full-static, and neither is
decided here.
master
Alexandre Gomes Gaigalas 3 weeks ago committed by GitHub
parent 69daefafb5
commit b831dfacf8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 24
      src/Platform/Macos.php
  2. 30
      src/Platform/UnixPlatform.php
  3. 9
      src/Platform/Wasi.php

@ -76,28 +76,4 @@ class Macos extends UnixPlatform
self::HOMEBREW_LIBRARY_PATHS,
)));
}
/**
* 获取默认的 RPATH 路径列表(macOS 需要)
*/
public function getDefaultRpaths(?string $phpxDir = null, ?string $phpDir = null): array
{
$rpaths = [];
if ($phpxDir !== null) {
$phpxLibDir = $phpxDir . '/lib';
if (is_dir($phpxLibDir)) {
$rpaths[] = $phpxLibDir;
}
}
if ($phpDir !== null) {
$phpLibDir = $this->resolvePhpLibDir($phpDir);
if ($phpLibDir !== null) {
$rpaths[] = $phpLibDir;
}
}
return $rpaths;
}
}

@ -166,6 +166,36 @@ abstract class UnixPlatform extends PlatformBase
throw new \RuntimeException('The `php-config` is not found. Please install PHP development package or set PHP_HOME environment variable');
}
/**
* libphpx and the embed libphp.so live where TypePHP put them: beside the
* phpx checkout, and under the PHP prefix the libphp installer chose.
* Neither is on the loader's search path, so a linked program only finds
* them again if their directories are recorded in the binary.
*
* Cross-compilation targets override this back to an empty list: a path on
* the build host means nothing on the device that runs the output.
*/
public function getDefaultRpaths(?string $phpxDir = null, ?string $phpDir = null): array
{
$rpaths = [];
if ($phpxDir !== null) {
$phpxLibDir = $phpxDir . '/lib';
if (is_dir($phpxLibDir)) {
$rpaths[] = $phpxLibDir;
}
}
if ($phpDir !== null) {
$phpLibDir = $this->resolvePhpLibDir($phpDir);
if ($phpLibDir !== null) {
$rpaths[] = $phpLibDir;
}
}
return $rpaths;
}
/**
* Get the RPATH options.
*/

@ -23,6 +23,15 @@ final class Wasi extends UnixPlatform
return '.a';
}
/**
* A WASI module resolves no shared libraries, and the build host's paths
* do not exist wherever it runs.
*/
public function getDefaultRpaths(?string $phpxDir = null, ?string $phpDir = null): array
{
return [];
}
public function getExecutableExtension(): string
{
return '.wasm';

Loading…
Cancel
Save