NeuronRobotics / nrjavaserial

A Java Serial Port system. This is a fork of the RXTX project that uses in jar loading of the native code.
Other
344 stars 143 forks source link

Support for Apple Silicon (macOS on AArch64) #195

Open MrDOS opened 3 years ago

MrDOS commented 3 years ago

This issue is a rallying point for future AArch64 porting as much as anything. I've taken a quick stab at hacking a Universal 2 build onto my refactored native build process (#189). Superficially, I think that what I have might be okay, but the build failed miserably. It failed deep in the bowels of a system header indirectly included from jni.h; assuming I got my compiler flags set correctly, I interpret this as meaning that Java (or at least, JNI) on AArch64 macOS is not yet ready for prime time. I'll check again in a month or two when a new Xcode beta is released and Travis bumps the Xcode build version for the xcode12u image from “Xcode 12 for macOS Universal Apps Beta 2”/12A8161k.

MrDOS commented 3 years ago

Azul have builds of OpenJDK for AArch64 available now. I should be able to download and extract one of those archives and use its contents as the JAVA_HOME for the AArch64 build.

Azul provides an API for locating downloads, but the macOS AArch64 builds don't appear to be visible there yet:

https://api.azul.com/zulu/download/community/v1.0/bundles/latest/binary/?jdk_version=8&bundle_type=jdk&os=macos&arch=arm&hw_bitness=64

In the meantime, a hacky workaround is to scrape the download URL from the downloads page:

download_page="$(curl -sL https://www.azul.com/downloads/zulu-community/)"
# JDK “bandles” (bands of bundles? Typo?) are defined as JSON in the page.
bandles="$(echo "$download_page" | grep -m 1 "bandles:" | sed -e 's/^\s*bandles:\s*sortArray(\s*//;s/),$//')"
# Use jq to filter the JSON for the JDK 8 bandle for macOS on AArch64, and extract its download link.
jdk_url="$(echo "$bandles" | jq -r 'map(select((.["category_slug"] == "java-8-lts") and (.["os_slug"] | map(. == "macos") | any) and (.["arch_slug"] == "arm-64-bit")))[0]["bundles"][0]["link"]')"
MrDOS commented 3 years ago

I've rebased onto the latest version of my refactored native builds (#189) in the build-universal-macos-binary branch of my development fork. Using the Azul Zulu build of OpenJDK as described above, the universal binary builds!

I need to confirm that this build still works correctly on Intel-based macOS. I don't anticipate any problems, but I do still need to confirm that I haven't broken anything. After that, I'll have taken this basically as far as I can. There are no changes required to the Java loading code to support this, because NativeResource already expects the macOS library to be multi-arch (inasmuch as it blindly loads the same library file on macOS regardless of the runtime architecture). It will be some time before I can get hands-on time with an M1-equipped Mac to test this in the flesh, so I think I'd rather just ship it and see if it works in the wild. Can't be much worse than no support at all.

MrDOS commented 10 months ago

Last week, I rebased my branch onto https://github.com/NeuronRobotics/nrjavaserial/pull/238, and included the loader changes that @ArtRoman pointed out in https://github.com/NeuronRobotics/nrjavaserial/issues/219. I was then able to smoke-test that build on macOS 12.6 on ARM64 and Mac OS X 10.9 on x86_64. I plan to submit a PR for that branch after #238 merges.

Per the project milestones I set up a few years ago, I was planning for the next library release (v5.3.0) to be a purely bugfix release, and to put this work into the subsequent release (v5.4.0); but we've picked up two other platform support changes in the meantime (https://github.com/NeuronRobotics/nrjavaserial/pull/218, https://github.com/NeuronRobotics/nrjavaserial/pull/236), and this work is basically done, so we might as well include it.