The Nim 2.0 release candidate is out, and includes a whole host of amazing changes and additions. I had been holding off on exploring Nim because I was waiting for ORC and multi-threading to become the default. They have been available for a long time, but defaults matter - it’s what first time and first-time-in-a-while users experience. It forms their opinion of what the language is about.
Installing Nim on Apple Silicon Macs is pretty straight forward. The official installer sets up
choosenim and a default stable release:
curl https://nim-lang.org/choosenim/init.sh -sSf | sh
However, both Nim itself and the compiler output will be
amd64 (Intel) binaries. To go native, and to benefit from Nim 2 right now, more configuration is required.
Set up Nim 2 natively
We need a source build, and thankfully that’s easy:
git clone https://github.com/nim-lang/Nim cd Nim git checkout version-2-0 sh build_all.sh
Yep, that’s it. We don’t have to mess with our
PATH either. Instead, we can now point
choosenim at the new build:
And confirm the architecture with:
$ nim -v Nim Compiler Version 1.9.1 [MacOSX: arm64] Compiled at 2023-01-14 Copyright (c) 2006-2022 by Andreas Rumpf
(2.0 RC self-reports as 1.9.1 as of Jan 15 2023)
To switch back, use
Native & universal binaries
Building a project with this toolchain will produce an Intel binary. To get a full build on macOS, we have to follow Apple’s guidelines and set the correct compiler and linker targets. In your project’s nimble (
nimble init if you don’t have one yet), add a new target:
task release_clang, "Build a production release (macOS)": --verbose --forceBuild:on --cc:clang --define:release --deepcopy:on --cpu:arm64 --passC:"-flto -target arm64-apple-macos11" --passL:"-flto -target arm64-apple-macos11" --hints:off --outdir:"." setCommand "c", "hello.nim"
-fltois required because clang doesn’t like Nim’s default passing of LTO parameters
- note the
- the rest are standard release flags
threads are default now, so no need to enable them here anymore. It’s a good idea to pin the Nim version in the nimble file, in this case to
nimble release_clang now gives us a nice native binary:
$ file hello hello: Mach-O 64-bit executable arm64
If you want to build an Intel binary, add another task and change the target to
x86_64-apple-macos10.12. If you need a universal binary, build both the Intel and ARM targets first, then merge them using
lipo -create -output universal_app x86_app arm_app
BTW: If you’re wondering what the cover image is about - “Nimm 2” (“take two”) is a popular brand of gummy candy in Germany.