Get a working aarch64 box
This post show how to get a working aarch64 env on the MacBook Air (M1) for Haskell.
I’m working on the road at the moment, so picked up a MacBook Air with the M1 chip, to travel light. I wanted to use it as a development environment for Glean (c.f. what is Glean), the code search system I work on. But Glean is a Linux/x86_64 only at the moment due to use of some fancy AVX extensions deep down in the runtime. Let’s fix that.
Motivation: getting Glean working on Apple ARM chips could be useful for a few reasons. Apple Silicon is becoming really common, and a lot of devs have MacBooks as their primary development environment (essentially expensive dumb terminals to run VS Code). Glean is/could be the core of a lot of developer environments, as it indexes source code and serves up queries extremely efficiently, so it could be killer as a local language server backend for your Mac IDE. (e.g. a common backend for all your languages, with unified search, jump-to-def, find-refs etc).
Setup up UTM
Glean is still very Linux-focused. So we need a VM. I’m building on an M1 MacBook Air (ARM64). So I install UTM from the app store or internet – this will be our fancy iOS QEMU virtualization layer.
Configure the OS image as per https://medium.com/@lizrice/linux-vms-on-an-m1-based-mac-with-vscode-and-utm-d73e7cb06133 for aarch64 debian, using https://mac.getutm.app/gallery/ubuntu-20-04 for the basic configuration.
In particular, I set up the following.
- Information -> Style: Operating system
- System -> Hardware -> Architecture: aarch64
- System -> Memory -> 16G (compiling stuff!)
- Drives -> VirtIO at least 20G, this will be the install drive and build artifacts
- Drives -> Removable USB , for the installation .iso
- Display -> console only (we’ll use ssh)
- Network -> Mode: Emulated VLAN
I’ll point VS Code and other things at this VM, so I’m going to forward port 2200 on the Mac to port 22 on the Debian VM.
Choose OS installer and boot
Set the CD/DVD to the Debian ISO file path. I used the arm64 netinst iso for Debian 11 from https://cdimage.debian.org/debian-cd/current/arm64/iso-cd/
Boot the machine and run the Debian install. It’s like 1999 here. (So much nostalgia when I used to scavenge x86 boxes from dumpsters in the Sydney CBD 20 years ago to put Linux on them).
Boot the image and log in. Now we have a working Linux aarch64 box on the M1, running very close to native speed (arm on arm virtualization).
You can ssh into this from the Mac OS side, or set it up as a remote host for VS Code just fine, which is shockingly convenient (on port 2200).
Install the dev env
This is a really basic Debian image, so you need a couple of things to get started with a barebones Haskell env:
apt install sudo curl cabal-install
We have a basic dev env now.
$ uname -msr Linux 5.10.0-10-arm64 aarch64 $ ghci GHCi, version 8.8.4: https://www.haskell.org/ghc/ :? for help Prelude> System.Info.arch "aarch64" Prelude> let s = 1 : 1 : zipWith (+) s (tail s) in take 20 s [1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765]
To build Glean a la https://glean.software/docs/building/ we need to update Cabal to the 3.6.x or greater, as Glean uses some fancy Cabal configuration features..
We need cabal > 3.6.x which isn’t in Debian stable, so I’ll just use the pre-built binary from https://www.haskell.org/cabal/download.html
Choose: Binary download for Debian 10 (aarch64, requires glibc 2.12 or later): cabal-install-18.104.22.168-aarch64-linux-deb10.tar.xz
Unpack that. You’ll also need apt-get libnuma-dev if you use that binary.
$ tar xvfJ cabal-install-22.214.171.124-aarch64-linux-deb10.tar.xz $ ./cabal --version cabal-install version 126.96.36.199 compiled using version 188.8.131.52 of the Cabal library
I just copy that over the system cabal for great good. It’s a good idea now to sync the package list for Hackage, before we start trying to build anything Haskell. with a cabal update.
Install the Glean dependencies
To build Glean we need a bunch C++ things. Glean itself will bootstrap the Haskell parts. The Debian packages needed are identical to those for Ubuntu on the Glean install instructions : https://glean.software/docs/building/#ubuntu except you might see “Package ‘libmysqlclient-dev’ has no installation candidate”. We will instead need default-libmysqlclient-dev. We also need libfmt-dev.
So the full set of Debian Glean dependencies are:
> apt install g++ \ cmake \ bison flex \ git cmake \ libzstd-dev \ libboost-all-dev \ libevent-dev \ libdouble-conversion-dev \ libgoogle-glog-dev \ libgflags-dev \ libiberty-dev \ liblz4-dev \ liblzma-dev \ libsnappy-dev \ make \ zlib1g-dev \ binutils-dev \ libjemalloc-dev \ default-libmysqlclient-dev \ libssl-dev \ pkg-config \ libunwind-dev \ libsodium-dev \ curl \ libpcre3-dev \ libfftw3-dev \ librocksdb-dev \ libxxhash-dev \ libfmt-dev
Now we have a machine ready to build Glean. We’ll do the ARM port of Glean in the next post and get something running.