java-tree-sitter icon indicating copy to clipboard operation
java-tree-sitter copied to clipboard

Support Apple silicon

Open ivangreene opened this issue 2 years ago • 3 comments

Trying to load the dylib on Apple silicon gives this error:

Exception in thread "main" java.lang.UnsatisfiedLinkError: /private/var/folders/1b/331lr8s90xxcdx51x0pbwc7w0000gn/T/libjava-tree-sitter.dylib: dlopen(/private/var/folders/1b/331lr8s90xxcdx51x0pbwc7w0000gn/T/libjava-tree-sitter.dylib, 0x0001): tried: '/private/var/folders/1b/331lr8s90xxcdx51x0pbwc7w0000gn/T/libjava-tree-sitter.dylib' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64')), '/System/Volumes/Preboot/Cryptexes/OS/private/var/folders/1b/331lr8s90xxcdx51x0pbwc7w0000gn/T/libjava-tree-sitter.dylib' (no such file), '/private/var/folders/1b/331lr8s90xxcdx51x0pbwc7w0000gn/T/libjava-tree-sitter.dylib' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64'))
	at java.base/jdk.internal.loader.NativeLibraries.load(Native Method)
	at java.base/jdk.internal.loader.NativeLibraries$NativeLibraryImpl.open(NativeLibraries.java:388)
	at java.base/jdk.internal.loader.NativeLibraries.loadLibrary(NativeLibraries.java:232)
	at java.base/jdk.internal.loader.NativeLibraries.loadLibrary(NativeLibraries.java:174)
	at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2389)
	at java.base/java.lang.Runtime.load0(Runtime.java:755)
	at java.base/java.lang.System.load(System.java:1953)
	at ch.usi.si.seart.treesitter.LibraryLoader.load(LibraryLoader.java:73)
	at org.example.Main.<clinit>(Main.java:11)

Important part being (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64'))

This is revealed with lipo:

$ lipo -archs libjava-tree-sitter.dylib
x86_64

It should be possible to create a universal binary using something like this method: https://developer.apple.com/documentation/apple-silicon/building-a-universal-macos-binary#Update-the-Architecture-List-of-Custom-Makefiles

ivangreene avatar Dec 19 '23 02:12 ivangreene

Hi @ivangreene

Thank you for the report. Unfortunately, this is a long-standing issue that we are very much aware of. The original developers wrote the build script used for this project. The file is quite messy and will most likely be rewritten from scratch soon. The way it works is it builds for only one specified OS and architecture at a time. At the same time, when we build for release we do it locally on one of our machines, before publishing to Maven Central. Since we use only one machine with specific specs, we can only reliably compile for the x86_64 architecture. We plan to address this by migrating our build, test and release to GitHub actions, which will allow us to support a wider range of architectures.

Currently, the only way to work around the issue is to compile the JAR yourself locally and include it in your project. Since you are running this on MacOS you would need to modify the build-shared-object-library-macos execution to include the appropriate architecture parameter:

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>exec-maven-plugin</artifactId>
  <version>3.1.1</version>
  <executions>
    <!-- OMITTED FOR BREVITY -->
    <execution>
      <id>build-shared-object-library-macos</id>
      <phase>compile</phase>
      <goals>
        <goal>exec</goal>
      </goals>
      <configuration>
        <executable>python3</executable>
        <workingDirectory>${project.basedir}</workingDirectory>
        <arguments>
          <argument>build.py</argument>
+         <argument>-a</argument>
+         <argument>aarch64</argument>
          <argument>-o</argument>
          <argument>${project.build.outputDirectory}/libjava-tree-sitter</argument>
        </arguments>
      </configuration>
    </execution>
    <!-- OMITTED FOR BREVITY -->
  </executions>
</plugin>

Since you are compiling locally for just MacOS, you can also skip the Linux compilation entirely:

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>exec-maven-plugin</artifactId>
  <version>3.1.1</version>
    <!-- OMITTED FOR BREVITY -->
    <execution>
      <id>build-shared-object-library-linux</id>
      <phase>compile</phase>
      <goals>
        <goal>exec</goal>
      </goals>
      <configuration>
+       <skip>true</skip>
        <!-- OMITTED FOR BREVITY -->
      </configuration>
    </execution>
  </executions>
</plugin>

I'll keep the issue open for the moment, but it might be superseded by a more general one in the future.

dabico avatar Dec 19 '23 12:12 dabico

Thanks, looking forward to a build with both architectures in the future. As a note, the build works as-is locally because the build.py determines the host's architecture, so didn't need to add the argument in the pom

ivangreene avatar Dec 20 '23 02:12 ivangreene