I’ve built an amd64
snap that includes the OpenJDK JRE.
I’m working with a pre-built binary which expects the Java binary at /usr/bin/java8
. For amd64
, I’m able to solve this problem with a layout:
/usr/bin/java8:
symlink: $SNAP/usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java
The problem is that this symlink path is architecture-specific. If I build the snap on arm64
, the openjdk folder is not going to be under java-8-openjdk-amd64
. I’d like to use the Advanced Grammar feature, but that’s not allowed for layouts.
I’m installing the JRE as a stage-package, so it’s installed using apt
.
stage-packages:
...
- openjdk-8-jre-headless
What’s the path of least resistance to resolving this?
I don’t need other packages such as the JDK or full JRE and would rather not use the Java plugin.
I don’t know if there is any way to do this today either… but maybe we could support something like $SNAPCRAFT_ARCH, or otherwise allow a user to specify arch-dependent variables and apply them on layouts? @sergiusens
You could make a “trampoline” symlink in your snap which is arch-dependent and point the layout at that symlink, so you would have something like:
layout:
usr/bin/java8:
symlink: $SNAP/usr/bin/java-trampoline
parts:
symlink-trampoline:
plugin: nil
override-build:
mkdir -p $SNAPCRAFT_PART_INSTALL/usr/bin/
if [ "$(arch)" = "arm64" ]; then
ln -s ../../usr/lib/jvm/java-8-openjdk-arm64/jre/bin/java $SNAPCRAFT_PART_INSTALL/usr/bin/java-trampoline
elif [ "$(arch)" = "amd64" ]; then
...
Admittedly this is made awkward by the absence of --target-arch in modern snapcraft versions, so you can’t really use $SNAPCRAFT_ARCH_TRIPLET
1 Like
Thank you, that worked! I was trying to do something along those lines using raw layouts but wasn’t able to. I think your solution is best.
The following code works on amd64
. I haven’t been able to test on arm64
because of another issue (not on a raspberry pi), but It shouldn’t take many modifications to make it work. I’ll test armv7
soon.
...
parts:
mypart:
stage-packages:
...
- openjdk-8-jre-headless
override-build: |
# execute default build step
snapcraftctl build
cd "$SNAPCRAFT_PART_INSTALL/usr/lib/jvm" || exit 2
# This dir will be a symlink to java-8-openjdk-<arch>
OPENJDK_DIR_SYMLINK="java-8-openjdk-arch-symlink"
case $(arch) in
x86_64)
OPENJDK_DIR="java-8-openjdk-amd64"
;;
aarch64)
OPENJDK_DIR="java-8-openjdk-arm64"
;;
armv7l)
OPENJDK_DIR="java-8-openjdk-armhf"
;;
*)
echo "arch $(arch) not supported"
exit 3
;;
esac
ln -s "$OPENJDK_DIR" "$OPENJDK_DIR_SYMLINK" || \
(echo "failed to link $OPENJDK_DIR_SYMLINK -> $OPENJDK_DIR" \
&& exit 4)
...
layout:
...
/usr/bin/java8:
symlink: $SNAP/usr/lib/jvm/java-8-openjdk-arch-symlink/jre/bin/java
1 Like
@ijohnson I would second making a $SNAPCRAFT_ARCH or similar. I am going to have to do the same thing that @zjoseal did in his snap to make this build on other platforms.
layout:
/usr/lib/girepository-1.0:
bind: $SNAP/usr/lib/x86_64-linux-gnu/girepository-1.0
/usr/lib/gio:
bind: $SNAP/usr/lib/x86_64-linux-gnu/gio
for girepository and gio, you can do:
layout:
/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/girepository-1.0:
bind: $SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/girepository-1.0
/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/gio:
bind: $SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/gio
Presumably, @cjp256 mentioned $SNAPCRAFT_ARCH
as a potential comparable variable to $SNAPCRAFT_ARCH_TRIPLET
that includes just the architecture instead of the full GNU Toolchain triplet.
@lucyllewy Awesome, Thanks!