How to build application in arm64 arch with a x86_64 host

my computer is x86_64 arch. how to build my application in arm64 arch.

This depends a lot on what you are targeting.
x86_64-linux → aarch64-linux works fairly well.

You will need a toolchain for your target, and the relevant ghc cross compiler. I did write quite a bit about this on https://log.zw3rk.com years ago. Most of that has gone into either GHC or haskell.nix, although that basically requires getting familiar with nix to a certain degree.

2 Likes

I am try to build application in a ARM64 docker container. but got this error:

root âžś / $ uname -a
Linux d2e8f319e072 5.15.90.1-microsoft-standard-WSL2 #1 SMP Fri Jan 27 02:56:13 UTC 2023 aarch64 GNU/Linux
root âžś / $ stack new helloworld new-template
root âžś / $ cd helloworld
root âžś /helloworld $ stack build
Preparing to install GHC (tinfo6-libc6-pre232) to an isolated location. This will not interfere with any system-level installation.
Already downloaded ghc-tinfo6-libc6-pre232-9.4.6.
ar: conftest.a: No such file or directory

May I ask, what is the Linux distribution in your ARM64 docker container? If it is Alpine Linux, only the master branch version of Stack supports it.

If you are using a docker container, you are technically natively compiling. Anything in the docker container won’t see that it’s not on aarch64.

running stack on a x86_64 container , but got killed:

my computer is macOS M1:

I started the container with: docker run --platform=linux/amd64 -it --rm haskell:9

As @angerman says, first you need an aarch64 cross-compilation toolchain with GCC etc. For me on Arch Linux, this just requires running sudo aura -A aarch64-none-linux-gnu-gcc-9.2-bin.

Then the annoying part is that GHC is not “runtime-retargetable” (though it will be soon, possibly in 9.10!), which means you need to get hold of a version which targets aarch64. It’s fairly simple to build this yourself. My most recent success was with this (taking just under an hour on a decent-spec laptop):

echo '
V=0
BUILD_MAN = NO
BUILD_SPHINX_HTML = NO
BUILD_SPHINX_PDF = NO
HADDOCK_DOCS = NO
Stage1Only = YES
BuildFlavour = quick
WITH_TERMINFO = NO
BIGNUM_BACKEND = native
' > build.mk

time ghcup compile ghc -v 9.2.7 -b 9.0.2 -x aarch64-none-linux-gnu -c $(pwd)/build.mk

This uses a native x86_64 GHC 9.0.2 to build an aarch64-targeting GHC 9.2.7. I’d prefer to build a more recent GHC but after 9.2 it has a new build system “Hadrian” for which I believe GHCup has only fledgling support. At least I believe this explains why time ghcup compile ghc --hadrian -v 9.4.7 -b 9.4.5 -x aarch64-none-linux-gnu -c $(pwd)/build.mk --set falls over after about 15 minutes with weird no such instruction errors. I haven’t really looked in to the details enough yet to go pestering @hasufell with a bug report.

I also sometimes use Haskell.Nix for cross-compiling, which is good for reproducibility, but brings its own complexities.

Building cross compilers via hadrian works in GHCup, see [ANN] GHCup-0.1.19.5 release candidate (GHC JS cross support)

build.mk isn’t used anymore. You’ll have to read up on build flavours and flavour transformers.

The easiest for something adhoc I’ve found is using binfmt emulatedsystems (this setting on nixos NixOS Search) you just build the target for aarch64. This doesn’t require cross compiling, your host and target will both be aarch64 from the compilers eyes

Disclaimer:
I don’t know whether it’s as easy to use it on non nixos.

1 Like

Oh cool. Specifying flavours gets me a step further, in that I can now “successfully” build with ghcup -v compile ghc --hadrian -v 9.6.2 -b 9.6.2 -x aarch64-linux-gnu -j $(nproc) --flavour=quick+native_bignum. But the GHC produced fails with no such instruction errors when compiling Hello World. I guess I’ll report the issue to GHC.

PS. It’s also much quicker, taking only twenty minutes on my machine instead of an hour. This might just be that I wasn’t specifying any equivalent of -j with the Make system (if it was even possible?).

I’d prefer to build a more recent GHC but after 9.2 it has a new build system “Hadrian” for which I believe GHCup has only fledgling support.

Hadrian isn’t that new - it’s 5 years old. GHCup is newer than Hadrian.

True, I was simplifying for OP’s sake. It does only seem to have fully taken over very recently.