How to run SBT on Apple Silicon

It is quite simple after a couple of days of fixing.

I assume that you’re using MacPorts that is working :)

First, you need something that we call bootstrap java. AdoptOpenJDK 1.8 isn’t ported and MacPorts complains about it, but we need it.

So, let install it and SBT.

catap@Kirills-mini-m1 ~ % sudo port install openjdk8 sbt  
---> Installing openjdk8 @8u275_0
---> Activating openjdk8 @8u275_0
---> Cleaning openjdk8
---> Computing dependencies for sbt
---> Fetching archive for sbt
---> Attempting to fetch sbt-0.13.18_0.darwin_20.noarch.tbz2 from https://packages.macports.org/sbt
---> Attempting to fetch sbt-0.13.18_0.darwin_20.noarch.tbz2 from https://lil.fr.packages.macports.org/sbt
---> Attempting to fetch sbt-0.13.18_0.darwin_20.noarch.tbz2 from https://nue.de.packages.macports.org/sbt
---> Fetching distfiles for sbt
Warning: Failed to confirm that required Java was installed; see https://trac.macports.org/ticket/61445
---> Verifying checksums for sbt
---> Extracting sbt
---> Configuring sbt
---> Building sbt
---> Staging sbt into destroot
---> Installing sbt @0.13.18_0
---> Activating sbt @0.13.18_0
---> Cleaning sbt
---> Updating database of binaries
---> Scanning binaries for linking errors
---> Found 8 broken files, matching files to ports
---> Found 1 broken port, determining rebuild order
You can always run 'port rev-upgrade' again to fix errors.
The following ports will be rebuilt: openjdk8 @8u275
Continue? [Y/n]: n
---> Some of the ports you installed have notes:
openjdk8 has the following notes:
If you have more than one JDK installed you can make openjdk8 the default
by adding the following line to your shell profile:

export JAVA_HOME=/Library/Java/JavaVirtualMachines/openjdk8/Contents/Home
catap@Kirills-mini-m1 ~ %

Good, we have very old SBT-0.13.8 and JDK that isn’t native and ports complaints to it. Let start to fix it.

Now we need a brand, new, unreleased (yet) SBT that we will use as boot sbt. Let build one. To do that we need unreleased upstream from SBT and one patch to switch some dependencies to the latest version that contains fixes.

catap@Kirills-mini-m1 ~ % mkdir -p ~/src
catap@Kirills-mini-m1 ~ % cd ~/src
catap@Kirills-mini-m1 src % git clone https://github.com/sbt/sbt.git
Cloning into 'sbt'...
remote: Enumerating objects: 238, done.
remote: Counting objects: 100% (238/238), done.
remote: Compressing objects: 100% (169/169), done.
remote: Total 112828 (delta 81), reused 147 (delta 44), pack-reused 112590
Receiving objects: 100% (112828/112828), 25.58 MiB | 14.42 MiB/s, done.
Resolving deltas: 100% (52326/52326), done.
catap@Kirills-mini-m1 src % cd sbt
catap@Kirills-mini-m1 sbt % curl -s https://gist.githubusercontent.com/catap/8396d51fbb0242e800aa05e395f16366/raw/656c532757f710e07ad177a4154f59968d0c780d/sbt-dependencies.patch | patch -p1
patching file build.sbt
patching file project/Dependencies.scala
patch unexpectedly ends in middle of line
Hunk #1 succeeded at 26 with fuzz 1.
catap@Kirills-mini-m1 sbt % sbt publishLocal > /dev/null
catap@Kirills-mini-m1 sbt %

Good, now we should flush boot cache of sbt:

catap@Kirills-mini-m1 sbt % rm -rf ~/.sbt/boot
catap@Kirills-mini-m1 sbt %

force SBT to use our version:

catap@Kirills-mini-m1 sbt % cat > ~/.sbtconfig
JAVA_OPTS="-Dsbt.version=1.5.0-SNAPSHOT"
^D
catap@Kirills-mini-m1 sbt %

and switch IPC inside SBT to TCP

catap@Kirills-mini-m1 sbt % cat > ~/.sbt/1.0/global.sbt 
Global / serverConnectionType := ConnectionType.Tcp
^D
catap@Kirills-mini-m1 sbt %

Good. Now we can remove AdoptOpenJDK and install ZuluJDK8 or ZuluJDK11 that is native for this platform:

catap@Kirills-mini-m1 sbt % sudo port uninstall openjdk8
Note: It is not recommended to uninstall/deactivate a port that has dependents as it breaks the dependents.
The following ports will break:
sbt @0.13.18_0
sbt @0.13.18_0
Continue? [y/N]: y
Warning: Uninstall forced. Proceeding despite dependencies.
---> Deactivating openjdk8 @8u275_0
---> Cleaning openjdk8
---> Uninstalling openjdk8 @8u275_0
---> Cleaning openjdk8
catap@Kirills-mini-m1 sbt % sudo port install zulu-jdk11
---> Computing dependencies for zulu-jdk11
---> Fetching distfiles for zulu-jdk11
---> Verifying checksums for zulu-jdk11
---> Extracting zulu-jdk11
---> Configuring zulu-jdk11
---> Building zulu-jdk11
---> Staging zulu-jdk11 into destroot
Warning: zulu-jdk11 installs files outside the common directory structure.
---> Installing zulu-jdk11 @11.43.1007_0
---> Activating zulu-jdk11 @11.43.1007_0
---> Cleaning zulu-jdk11
---> Updating database of binaries
---> Scanning binaries for linking errors
---> No broken files found.
---> No broken ports found.
---> Some of the ports you installed have notes:
zulu-jdk11 has the following notes:
If you have more than one JDK installed you can make zulu-jdk11 the default
by adding the following line to your shell profile:

export JAVA_HOME=/Library/Java/JavaVirtualMachines/zulu-jdk11/Contents/Home
catap@Kirills-mini-m1 sbt %

Congrats! You have SBT that is working fine on Apple Silicon.

catap@Kirills-mini-m1 sbt % mkdir -p /tmp/sbt-test 
catap@Kirills-mini-m1 sbt % cd /tmp/sbt-test
catap@Kirills-mini-m1 sbt-test % sbt
[info] Updated file /private/tmp/sbt-test/project/build.properties: set sbt.version to 1.5.0-SNAPSHOT
[info] welcome to sbt 1.5.0-SNAPSHOT (Azul Systems, Inc. Java 11.0.9.1)
[info] loading project definition from /private/tmp/sbt-test/project
[info] set current project to sbt-test (in build file:/private/tmp/sbt-test/)
[info] sbt server started at tcp://127.0.0.1:5715
[info] started sbt server
sbt:sbt-test>

I hope soon everything will be merged, and you will need just upgrade SBT.

P.S. SBT 1.4.3 supports Apple Silicon. You can use 1.4.x branch and do not apply any patches.

IT geek who loves to play with the data. Would like to contact me? Just drop an email to kirill@korins.ky

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store