YMMV, but from my own experiments, on an M1 Macbook Air, it did not work well for me. I was trying to compile an Elixir codebase on x86-64 Alpine Linux. Elixir does not have cross-compiling. I tried it in a Docker container, and in a Linux VM using OrbStack. Both approaches fail, as it just segfaults, even on the first `mix compile` of a blank project.
This problem does not exist in ARM containers or VMs, as the same project compiles perfectly in an ARM Alpine Linux container/VM.
It's definitely not plug-and-play for all scenarios. If anyone knows workarounds, let me know.
That’s an underlying QEMU bug, which is used by Lima [1].
Add `ENV ERL_FLAGS="+JPperf true"` to your Dockerfile and it will build just fine cross platform. The flag just changes some things during build time and won’t affect runtime performance.
In that case can this whole thread be deleted and replaced by a link to an almost completely unrelated issue that used some of the same English words in the description? Just trying to get the full effect here.
For anything that doesn't need a UI, you're FAR better off having some remote server than trying to emulate, it's far to slow for ARM64<>x86-64 in both directions..
Many things are just so much easier with a remote server/workstation somewhere than trying to deal with VM shenanigans.
ARM64 visualised on the otherhand (Linux works great, macos seems good(?), haven't tried Windows) with UTM is pretty great.
I absolutely agree! I finally went in that direction. The only reason I was trying this whole ordeal was because I was trying to get some private dependencies included in the build without going through the whole hassle of git submodules. Now I just include those deps as a path include in mix.exs. Not a great solution I know...
I’ve been able to do this (build x86/ubuntu targeted elixir) with UTM on my M1 Mac. It ain’t fast, that’s for sure. But it works. Which is interesting because sibling responses to your Lima experience claim it’s because of a qemu “bug”, but utm runs qemu as well.
You're right that Elixir source code compiles to BEAM bytecode, however, if you run `mix release`, you need to ensure that the release runs on the same target OS and OpenSSL version. My aim was to build a `mix release` on my M1 Mac to run it on an x86-64 server.
From the docs [0]:
> Once a release is assembled, it can be packaged and deployed to a target, as long as the target runs on the same operating system (OS) distribution and version as the machine running the mix release command.
The `mix release` command outputs a directory containing your compiled Elixir bytecode files, along with the ERTS (Erlang Runtime System). The ERTS it bundles is only for your host machine's architecture. Another point to remember is that some dependencies use native NIFs, which means they need to be cross-compiled too. Hence it's not as easy as replacing the ERTS folder with one for another architecture in most circumstances.
There's a project that aims to alleviate these issues called Burrito [1], but when I tried it, I had mixed success with it, and decided not to use it for my deployment approach. It looks like Burrito has matured since then, so it would be worth taking a look into if you need to cross-compile.
The gist is, while possible, its significantly harder to get an Elixir release running on another architecture than say is the case for Go.
This problem does not exist in ARM containers or VMs, as the same project compiles perfectly in an ARM Alpine Linux container/VM.
It's definitely not plug-and-play for all scenarios. If anyone knows workarounds, let me know.