Skip to content

Commit 704082f

Browse files
authored
Add a way to override library paths using system properties (#120)
* Add library path override system properties * Bump version to 1.3.0
1 parent b45a6e8 commit 704082f

File tree

5 files changed

+59
-9
lines changed

5 files changed

+59
-9
lines changed

.github/workflows/checks.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ jobs:
5555

5656
- name: Run samples
5757
run: |
58-
vips --version || brew install vips
58+
vips --version || ((brew install pkgconf || brew link --overwrite pkgconf) && brew install vips)
5959
./run_samples.sh
6060
6161
windows-sense-check:

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ repositories {
2323
}
2424

2525
dependencies {
26-
implementation("app.photofox.vips-ffm:vips-ffm-core:1.2.2")
26+
implementation("app.photofox.vips-ffm:vips-ffm-core:1.3.0")
2727
}
2828
```
2929
When running your project you must add `--enable-native-access=ALL-UNNAMED` to your JVM runtime arguments. If you
@@ -172,6 +172,12 @@ yet (which could manifest as crashes/segfaults):
172172
* `vipsffm.abinumber.glib.override`, default: `0`
173173
* `vipsffm.abinumber.gobject.override`, default: `0`
174174

175+
If you want to manually override the library lookup path for any of the above (for example, if you're using a platform
176+
like Android where it's hard to set the system library path), you can do so using these system properties:
177+
* libvips: `vipsffm.libpath.vips.override` (eg `/opt/homebrew/lib/libvips.dylib`)
178+
* glib: `vipsffm.libpath.glib.override`
179+
* gobject: `vipsffm.libpath.gobject.override`
180+
175181
## Project goals
176182

177183
Ideas and suggestions are welcome, but please make sure they fit in to these goals, or you have a good argument about

core/src/main/java/app/photofox/vipsffm/VipsLibLookup.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import java.lang.foreign.Arena;
44
import java.lang.foreign.SymbolLookup;
5+
import java.nio.file.Path;
56
import java.util.List;
67
import java.util.Optional;
78

@@ -25,6 +26,10 @@ public static SymbolLookup buildSymbolLoader(Arena arena) {
2526
}
2627

2728
private static SymbolLookup findVipsLoader(Arena arena) {
29+
var overrideLookup = makeOptionalLibraryLookup("vips", arena);
30+
if (overrideLookup.isPresent()) {
31+
return overrideLookup.get();
32+
}
2833
var abiNumber = Optional.ofNullable(System.getProperty("vipsffm.abinumber.vips.override"))
2934
.orElse("42");
3035
var names = List.of(
@@ -36,6 +41,10 @@ private static SymbolLookup findVipsLoader(Arena arena) {
3641
}
3742

3843
private static SymbolLookup findGlibLoader(Arena arena) {
44+
var overrideLookup = makeOptionalLibraryLookup("glib", arena);
45+
if (overrideLookup.isPresent()) {
46+
return overrideLookup.get();
47+
}
3948
var abiNumber = Optional.ofNullable(System.getProperty("vipsffm.abinumber.glib.override"))
4049
.orElse("0");
4150
var names = List.of(
@@ -47,6 +56,10 @@ private static SymbolLookup findGlibLoader(Arena arena) {
4756
}
4857

4958
private static SymbolLookup findGObjectLoader(Arena arena) {
59+
var overrideLookup = makeOptionalLibraryLookup("gobject", arena);
60+
if (overrideLookup.isPresent()) {
61+
return overrideLookup.get();
62+
}
5063
var abiNumber = Optional.ofNullable(System.getProperty("vipsffm.abinumber.gobject.override"))
5164
.orElse("0");
5265
var names = List.of(
@@ -79,4 +92,26 @@ static Optional<SymbolLookup> attemptLibraryLookup(String name, Arena arena) {
7992
return Optional.empty();
8093
}
8194
}
95+
96+
private static Optional<SymbolLookup> makeOptionalLibraryLookup(String libraryName, Arena arena) {
97+
var propertyPath = "vipsffm.libpath.%s.override".formatted(libraryName);
98+
var overridePath = Optional.ofNullable(System.getProperty(propertyPath));
99+
return overridePath.map(path -> {
100+
SymbolLookup symbolLookup;
101+
try {
102+
symbolLookup = SymbolLookup.libraryLookup(Path.of(path), arena);
103+
} catch (IllegalArgumentException exception) {
104+
throw makeOverriddenPathMissingException(libraryName, path);
105+
}
106+
return symbolLookup;
107+
});
108+
}
109+
110+
private static IllegalArgumentException makeOverriddenPathMissingException(
111+
String libraryName,
112+
String overridePath
113+
) {
114+
var message = "path override requested for %s, but library not found at path: %s".formatted(libraryName, overridePath);
115+
return new IllegalArgumentException(message);
116+
}
82117
}

docs/index.html

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ <h2 id="usage-heading">Usage</h2>
7070
}
7171

7272
dependencies {
73-
implementation(&quot;app.photofox.vips-ffm:vips-ffm-core:1.2.2&quot;)
73+
implementation(&quot;app.photofox.vips-ffm:vips-ffm-core:1.3.0&quot;)
7474
}
7575
</code></pre>
7676
<p>When running your project you must add <code>--enable-native-access=ALL-UNNAMED</code> to your JVM runtime arguments. If you
@@ -122,8 +122,7 @@ <h3 id="thumbnail-sample-heading">Thumbnail sample</h3>
122122
Vips.run { arena -&gt;
123123
val sourceImage = VImage.newFromFile(
124124
arena,
125-
&quot;sample/src/main/resources/sample_images/rabbit.jpg&quot;,
126-
VipsOption.Enum(&quot;access&quot;, VipsAccess.ACCESS_SEQUENTIAL) // example of an option
125+
&quot;sample/src/main/resources/sample_images/rabbit.jpg&quot;
127126
)
128127
val sourceWidth = sourceImage.width
129128
val sourceHeight = sourceImage.height
@@ -132,9 +131,9 @@ <h3 id="thumbnail-sample-heading">Thumbnail sample</h3>
132131
val outputPath = workingDirectory.resolve(&quot;rabbit_copy.jpg&quot;)
133132
sourceImage.writeToFile(outputPath.absolutePathString())
134133

135-
val thumbnail = sourceImage.thumbnail(
136-
&quot;sample/src/main/resources/sample_images/rabbit.jpg&quot;,
137-
400
134+
val thumbnail = sourceImage.thumbnailImage(
135+
400,
136+
VipsOption.Boolean(&quot;auto-rotate&quot;, true) // example of an option
138137
)
139138
val thumbnailWidth = thumbnail.width
140139
val thumbnailHeight = thumbnail.height
@@ -218,6 +217,13 @@ <h2 id="native-library-loading-heading">Native library loading</h2>
218217
<li><code>vipsffm.abinumber.glib.override</code>, default: <code>0</code></li>
219218
<li><code>vipsffm.abinumber.gobject.override</code>, default: <code>0</code></li>
220219
</ul>
220+
<p>If you want to manually override the library lookup path for any of the above (for example, if you're using a platform
221+
like Android where it's hard to set the system library path), you can do so using these system properties:</p>
222+
<ul>
223+
<li>libvips: <code>vipsffm.libpath.vips.override</code> (eg <code>/opt/homebrew/lib/libvips.dylib</code>)</li>
224+
<li>glib: <code>vipsffm.libpath.glib.override</code></li>
225+
<li>gobject: <code>vipsffm.libpath.gobject.override</code></li>
226+
</ul>
221227
<h2 id="project-goals-heading">Project goals</h2>
222228
<p>Ideas and suggestions are welcome, but please make sure they fit in to these goals, or you have a good argument about
223229
why a goal should change!</p>

run_samples.sh

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,15 @@ set -eou pipefail
44
echo "building samples..."
55
./gradlew sample:clean sample:shadowJar
66

7+
export JAVA_PATH_OPTS=""
78
if [[ "$OSTYPE" == "darwin"* ]]; then
89
export DYLD_LIBRARY_PATH=/opt/homebrew/lib
10+
# this tests the library path override feature
11+
export JAVA_PATH_OPTS="-Dvipsffm.libpath.vips.override=/opt/homebrew/lib/libvips.dylib"
912
fi
1013

1114
echo "running samples..."
12-
java -jar sample/build/libs/sample-all.jar 2>&1 | tee sample_output.log
15+
java $JAVA_PATH_OPTS -jar sample/build/libs/sample-all.jar 2>&1 | tee sample_output.log
1316

1417
echo "checking for leaks..."
1518
if grep --quiet "objects alive:" sample_output.log; then

0 commit comments

Comments
 (0)