Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 3ae9a3b

Browse files
Add FFI::addLibraryPath utility
In favor of the `VIPSHOME` env. Resolves: #232.
1 parent efbf4c4 commit 3ae9a3b

File tree

2 files changed

+51
-25
lines changed

2 files changed

+51
-25
lines changed

‎README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ To your `php.ini`.
7373
require __DIR__ . '/vendor/autoload.php';
7474
use Jcupitt\Vips;
7575

76+
// handy for Windows
77+
Vips\FFI::addLibraryPath("C:/vips-dev-8.16/bin");
78+
7679
// check libvips version
7780
echo 'libvips version: ' . Vips\Config::version() . PHP_EOL;
7881

‎src/FFI.php

Lines changed: 48 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,15 @@ class FFI
7979
*/
8080
private static bool $ffi_inited = false;
8181

82+
/**
83+
* A list of paths where libvips might reside.
84+
*
85+
* @internal
86+
*/
87+
private static array $libraryPaths = [
88+
"" // system library
89+
];
90+
8291
/**
8392
* Look up these once.
8493
*
@@ -169,6 +178,30 @@ public static function atLeast(int $x, int $y, int $z = 0): bool
169178
self::$library_micro >= $z);
170179
}
171180

181+
/**
182+
* Adds a directory to the search path for shared libraries.
183+
*
184+
* This method has no effect if FFI handles are already initialized or
185+
* if the specified path is already included.
186+
*
187+
* @param string $path The path of the library.
188+
* @return bool `true` if the path was added; otherwise, `false`.
189+
*/
190+
public static function addLibraryPath(string $path): bool
191+
{
192+
// Already initialized.
193+
if (self::$ffi_inited) {
194+
return false;
195+
}
196+
197+
if (!in_array($path, self::$libraryPaths)) {
198+
self::$libraryPaths[] = $path;
199+
return true;
200+
}
201+
202+
return false;
203+
}
204+
172205
/**
173206
* Shut down libvips. Call this just before process exit.
174207
*
@@ -208,14 +241,16 @@ private static function libraryName(string $name, int $abi): string
208241
}
209242

210243
private static function libraryLoad(
211-
array $libraryPaths,
212244
string $libraryName,
213245
string $interface
214246
): ?\FFI {
215247
Utils::debugLog("trying to open", ["libraryName" => $libraryName]);
216-
foreach ($libraryPaths as $path) {
248+
foreach (self::$libraryPaths as $path) {
217249
Utils::debugLog("trying path", ["path" => $path]);
218250
try {
251+
if ($path !== '') {
252+
$path .= '/';
253+
}
219254
$library = \FFI::cdef($interface, $path . $libraryName);
220255
Utils::debugLog("success", []);
221256
return $library;
@@ -252,37 +287,25 @@ private static function init(): void
252287

253288
$is_64bits = PHP_INT_SIZE === 8;
254289

255-
$libraryPaths = [
256-
"" // system library
257-
];
258-
259-
$vipshome = getenv("VIPSHOME");
260-
if ($vipshome) {
261-
// lib<qual>/ predicates lib/
262-
$libraryPaths[] = $vipshome . ($is_64bits ? "/lib64/" : "/lib32/");
263-
// lib/ is always searched
264-
$libraryPaths[] = $vipshome . "/lib/";
265-
}
266-
267290
if (PHP_OS_FAMILY === "OSX" || PHP_OS_FAMILY === "Darwin") {
268291
// Homebrew on Apple Silicon
269-
$libraryPaths[] = "/opt/homebrew/lib/";
292+
self::$libraryPaths[] = "/opt/homebrew/lib";
270293
// See https://github.com/Homebrew/brew/issues/13481#issuecomment-1207203483
271-
$libraryPaths[] = "/usr/local/lib/";
294+
self::$libraryPaths[] = "/usr/local/lib";
272295
}
273296

274-
$vips = self::libraryLoad($libraryPaths, $vips_libname, <<<'CPP'
297+
$vips = self::libraryLoad($vips_libname, <<<'CPP'
275298
int vips_init (const char *argv0);
276299
const char *vips_error_buffer (void);
277300
int vips_version(int flag);
278301
CPP);
279302

280303
if ($vips === null) {
281304
// drop the "" (system path) member
282-
array_shift($libraryPaths);
305+
array_shift(self::$libraryPaths);
283306
$msg = "Unable to open library '$vips_libname'";
284-
if (!empty($libraryPaths)) {
285-
$msg .= " in any of ['" . implode("', '", $libraryPaths) . "']";
307+
if (!empty(self::$libraryPaths)) {
308+
$msg .= " in any of ['" . implode("', '", self::$libraryPaths) . "']";
286309
}
287310
$msg .= ". Make sure that you've installed libvips and that '$vips_libname'";
288311
$msg .= " is on your system's library search path.";
@@ -777,13 +800,13 @@ private static function init(): void
777800
* one that libvips itself is using, and they will share runtime types.
778801
*/
779802
self::$glib =
780-
self::libraryLoad($libraryPaths, $vips_libname, $glib_decls) ??
781-
self::libraryLoad($libraryPaths, $glib_libname, $glib_decls);
803+
self::libraryLoad($vips_libname, $glib_decls) ??
804+
self::libraryLoad($glib_libname, $glib_decls);
782805
self::$gobject =
783-
self::libraryLoad($libraryPaths, $vips_libname, $gobject_decls) ??
784-
self::libraryLoad($libraryPaths, $gobject_libname, $gobject_decls);
806+
self::libraryLoad($vips_libname, $gobject_decls) ??
807+
self::libraryLoad($gobject_libname, $gobject_decls);
785808

786-
self::$vips = self::libraryLoad($libraryPaths, $vips_libname, $vips_decls);
809+
self::$vips = self::libraryLoad($vips_libname, $vips_decls);
787810

788811
# Useful for debugging
789812
# self::$vips->vips_leak_set(1);

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /