flow icon indicating copy to clipboard operation
flow copied to clipboard

Arm64 Build for Apple Silicon?

Open STRML opened this issue 3 years ago • 14 comments

Proposal

I would like to explore how we can configure CircleCI to build a native arm64 binary for macOS, so it can be used on M1 developer machines via flow-bin.

Use case

I was able to build flow on my M1 with the following small changes (ocamlbuild 4.10.2 or 4.12.0 is required for M1 support):

diff --git a/Makefile b/Makefile
index fa3bcbc80..a9bcf7ae0 100644
--- a/Makefile
+++ b/Makefile
@@ -25,7 +25,7 @@ ifeq ($(OS), Windows_NT)
 else
   UNAME_S=$(shell uname -s)
   UNAME_M=$(shell uname -m)
-  SWITCH=ocaml-base-compiler.4.09.1
+  SWITCH=ocaml-base-compiler.4.10.2
 endif

 # Default to `ocamlbuild -j 0` (unlimited parallelism), but you can limit it
diff --git a/README.md b/README.md
index 50e6bca4c..04c15846a 100644
--- a/README.md
+++ b/README.md
@@ -83,6 +83,7 @@ Flow is written in OCaml (OCaml 4.09.1 is required).
     ```sh
     # on Mac and Linux:
     opam init
+    opam update

     # on Windows:
     scripts/windows/init_opam.sh

The performance is substantially better (2x performance) than through Rosetta 2:

x86:
$ time flow check
Found 0 errors
✨  Done in 3.28s.

________________________________________________________
Executed in    3.52 secs   fish           external
   usr time  1005.93 millis   63.00 micros  1005.87 millis
   sys time  678.18 millis  1213.00 micros  676.97 millis
native arm64:
$ time ../flow/bin/flow check
Found 0 errors
________________________________________________________
Executed in    1.58 secs   fish           external
   usr time  634.83 millis   73.00 micros  634.76 millis
   sys time  331.76 millis  1190.00 micros  330.57 millis

I am not familiar enough with ocamlbuild to know if there is a way for us to output an ARM64 binary on an Intel Mac builder, as CircleCI does not yet provide M1 support.

I'm experimenting with how to get it working in this CircleCI job, but they are currently having an outage.

STRML avatar May 21 '21 14:05 STRML

@mroch Any progress on that? It's been almost a year since changes needed for Apple Silicon build were introduced https://github.com/facebook/flow/pull/8616 and it's been established that native arm64 build is 2x as fast as running Flow via Rosetta. I understand that setting up CI for this is troublesome, but by now, Apple Silicon is the new standard so native builds on Flow releases would be highly, highly appreciated

PS: If anyone reading this wants to use Apple Silicon builds today, "flow-bin": "npm:@nozbe/[email protected]", works (but I don't have the patience to compile new builds on every release)

radex avatar Mar 09 '22 13:03 radex

I know it's not nice to do, but really, bump.

I wonder if you could use the Docker ARM emulation to build it?

https://www.stereolabs.com/docs/docker/building-arm-container-on-x86/

FezVrasta avatar Apr 07 '22 10:04 FezVrasta

I think it should be possible to add it to the CircleCI job, I'll give it another go-around today, but that depends on FB staff wanting to merge it.

STRML avatar Apr 07 '22 11:04 STRML

I don't believe it will be possible to cross compile on an intel Mac without something like https://github.com/ocaml-cross/opam-cross-windows. The compiler and ppxs would need to be built for intel but the rest of the artifacts for M1. But happy to be surprised if you can get it working @STRML!

We will add this as soon as M1 hosts are available in CI.

mroch avatar Apr 07 '22 12:04 mroch

There may be a (slow) way to make this work using docker buildx in CircleCI, investigating that now.

STRML avatar Apr 07 '22 15:04 STRML

Yeah I'm way off base on that idea. You can use docker buildx on M1 machines to do x86_64 and arm64 builds for linux which will work both on MacOS and Linux hosts, because both of them are effectively running Linux kernels to run Docker.

If you want something that will work natively on MacOS (aarch64-apple-darwin), it's more of a problem. You really seem to need an actual M1 host, or you need a way of passing flags to gcc directly like in the Apple docs so you can build a universal binary.

I don't know enough about ocamlopt to really understand how to do this, and neither does Google as far as I've been able to take it. It is theoretically possible on MacOS >= 11 and XCode >= 12 to build universal binaries even on x86, but I don't know how to make that work within the OCaml toolchain.

STRML avatar Apr 09 '22 00:04 STRML

@STRML it looks like they found a solution using GitHub Actions here?

https://discuss.ocaml.org/t/cross-compiling-ocaml-with-github-actions/9154

FezVrasta avatar Jun 03 '22 12:06 FezVrasta

Hello? Isn't Facebook using the new Macs for development?

FezVrasta avatar Jan 21 '23 13:01 FezVrasta

we have internal M1 builds, yeah. we're still waiting on CircleCI to launch M1 runners to integrate with our external releases, which we're told is Real Soon Now. i'm frustrated it's taking so long as well...

mroch avatar Jan 21 '23 13:01 mroch

Looking at this, it looks like ARM mac is coming soon from CircleCI.

SamChou19815 avatar Jan 22 '23 03:01 SamChou19815

CircleCI roadmap says that it's released 🎉

Screenshot 2023-02-21 at 07 35 27

w01fgang avatar Feb 21 '23 07:02 w01fgang

Yes, you might see that we already started to build it on mac arm: https://app.circleci.com/pipelines/github/facebook/flow/5541/workflows/ed21b666-0e64-435f-88ca-1f1623ed0c51/jobs/97719

SamChou19815 avatar Feb 21 '23 17:02 SamChou19815

When can we expect the osx-arm64 build to be included in NPM flow-bin? That would be very helpful, thanks

radex avatar Mar 22 '23 14:03 radex

Any update on this? The ARM binary has been available for a while already but it's not yet included in npm releases.

FezVrasta avatar May 10 '23 11:05 FezVrasta