|
22 | 22 | }
|
23 | 23 | [$_, $pathToCheck, $targetDirectory] = $argv;
|
24 | 24 |
|
25 |
| -// All the paths where shared libraries can be found |
26 |
| -const LIB_PATHS = [ |
27 |
| - // System libraries |
28 |
| - '/lib64', |
29 |
| - '/usr/lib64', |
30 |
| - // Libraries we compiled from source are installed here |
31 |
| - '/tmp/bref/lib', |
32 |
| - '/tmp/bref/lib64', |
33 |
| -]; |
34 |
| - |
35 | 25 | $arch = 'x86';
|
36 | 26 | if (php_uname('m') !== 'x86_64') {
|
37 | 27 | $arch = 'arm';
|
|
44 | 34 | return ! str_contains($library, 'libgcrypt.so') && ! str_contains($library, 'libgpg-error.so');
|
45 | 35 | });
|
46 | 36 |
|
47 |
| -$requiredLibraries = listAllDependenciesRecursively($pathToCheck); |
| 37 | +$requiredLibraries = listDependencies($pathToCheck); |
48 | 38 | // Exclude existing system libraries
|
49 | 39 | $requiredLibraries = array_filter($requiredLibraries, function (string $lib) use ($librariesThatExistOnLambda) {
|
50 |
| - $keep = ! in_array(basename($lib), $librariesThatExistOnLambda, true); |
| 40 | + $isALibraryWeCompiled = str_starts_with($lib, '/tmp/bref/lib'); |
| 41 | + $doesNotExistInLambda = !in_array(basename($lib), $librariesThatExistOnLambda, true); |
| 42 | + $keep = $isALibraryWeCompiled || $doesNotExistInLambda; |
51 | 43 | if (! $keep) {
|
52 | 44 | echo "Skipping $lib because it's already in Lambda" . PHP_EOL;
|
53 | 45 | }
|
|
58 | 50 | foreach ($requiredLibraries as $libraryPath) {
|
59 | 51 | $targetPath = $targetDirectory . '/' . basename($libraryPath);
|
60 | 52 | echo "Copying $libraryPath to $targetPath" . PHP_EOL;
|
61 |
| - copy($libraryPath, $targetPath); |
| 53 | + $success = copy($libraryPath, $targetPath); |
| 54 | + if (! $success) { |
| 55 | + throw new RuntimeException("Could not copy $libraryPath to $targetPath"); |
| 56 | + } |
62 | 57 | }
|
63 | 58 |
|
64 | 59 |
|
65 | 60 | function listDependencies(string $path): array
|
66 | 61 | {
|
67 |
| - static $cache = []; |
68 |
| - if (!isset($cache[$path])) { |
69 |
| - echo $path . PHP_EOL; |
70 |
| - $asString = shell_exec("objdump -p '$path' | grep NEEDED | awk '{ print $2 }'"); |
71 |
| - if (!$asString) { |
72 |
| - $dependencies = []; |
73 |
| - } else { |
74 |
| - $dependencies = array_filter(explode(PHP_EOL, $asString)); |
| 62 | + // ldd lists the dependencies of a binary or library/extension (.so file) |
| 63 | + exec("ldd $path 2>&1", $lines); |
| 64 | + if (str_contains(end($lines), 'exited with unknown exit code (139)')) { |
| 65 | + // We can't use `ldd` on binaries (like /opt/bin/php) because it fails on cross-platform builds |
| 66 | + // so we fall back to `LD_TRACE_LOADED_OBJECTS` (which doesn't work for .so files, that's why we also try `ldd`) |
| 67 | + // See https://stackoverflow.com/a/35905007/245552 |
| 68 | + $output = shell_exec("LD_TRACE_LOADED_OBJECTS=1 $path 2>&1"); |
| 69 | + if (!$output) { |
| 70 | + throw new RuntimeException("Could not list dependencies for $path"); |
75 | 71 | }
|
76 |
| - $cache[$path] = array_map(fn(string $dependency) => findFullPath($dependency), $dependencies); |
77 |
| - } |
78 |
| - return $cache[$path]; |
79 |
| -} |
80 |
| - |
81 |
| -function findFullPath(string $lib): string { |
82 |
| - static $cache = []; |
83 |
| - if (isset($cache[$lib])) { |
84 |
| - return $cache[$lib]; |
| 72 | + $lines = explode(PHP_EOL, $output); |
85 | 73 | }
|
86 |
| - foreach (LIB_PATHS as $libPath) { |
87 |
| - if (file_exists("$libPath/$lib")) { |
88 |
| - $cache[$lib] = "$libPath/$lib"; |
89 |
| - return "$libPath/$lib"; |
| 74 | + $dependencies = []; |
| 75 | + foreach ($lines as $line) { |
| 76 | + $matches = []; |
| 77 | + if (preg_match('/=> (.*) \(0x[0-9a-f]+\)/', $line, $matches)) { |
| 78 | + $dependencies[] = $matches[1]; |
90 | 79 | }
|
91 | 80 | }
|
92 |
| - throw new RuntimeException("Dependency '$lib' not found"); |
93 |
| -} |
94 |
| - |
95 |
| -function listAllDependenciesRecursively(string $path): array |
96 |
| -{ |
97 |
| - $dependencies = listDependencies($path); |
98 |
| - $allDependencies = []; |
99 |
| - foreach ($dependencies as $dependency) { |
100 |
| - $allDependencies = array_merge($allDependencies, listAllDependenciesRecursively($dependency)); |
101 |
| - } |
102 |
| - return array_unique(array_merge($dependencies, $allDependencies)); |
| 81 | + return $dependencies; |
103 | 82 | }
|
0 commit comments