Setting Apple Mac M1 up for development

Setting Apple Mac M1 up for development

I recently got the new M1 mac mini and had some problems setting up the development environment and had to research things, this post is to present my findings and help people moving to M1.

Apple Mac M1 is a new SOC developed by Apple whose performance has been in talks for quite some time now. Quoting the description from their landing page:

M1 is here. Our first chip designed specifically for Mac, it delivers incredible performance, custom technologies, and revolutionary power efficiency. And it was designed from the very start to work with the most advanced desktop operating system in the world, macOS Big Sur. With a giant leap in performance per watt, every Mac with M1 is transformed into a completely different class of product. This isn’t an upgrade. It’s a breakthrough.

M1 is an ARM based chip and not all software development has been ported to ARM yet and hence, not everything works out of box. However, Apple has developed a binary translator Rosetta that can translate the instructions on the fly to equivalent ARM ones which allows you to run apps developed for the intel chip on m1 chip as well.

Some useful aliases you may want to consider

I have setup 2 aliases, one for running with rosetta, one for running directly.

alias irun="arch -x86_64"
alias mrun="arch -arm64e"

This would allow you to run programs through rosetta by irun and directly through mrun.

This also allows you to run your terminal without rosetta and you can run only non-m1 version programs through rosetta using irun.

Installing homebrew

Mac doesn't come with a package manager, but homebrew is a pretty great open source package manager developed for the mac ecosystem. You want to install two versions of homebrew, one that installs m1 binaries and other that installs intel binaries when m1 binaries are unavailable.

  1. Install m1 version by running
    mrun /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
    
  2. Install rosetta / intel version by running
    irun /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
    

This installs homebrew in two locations, /usr/local/Homebrew and /opt/homebrew. All m1 programs will be installed in /opt/homebrew prefix, and all intel programs will be installed in /usr/local/Homebrew prefix.

I also setup two new useful aliases for the same:

alias mbrew="mrun /opt/homebrew/bin/brew"
alias ibrew="irun /usr/local/bin/brew"

Ideally when you would want to install new software, you first want to search for arm version and then if not available, search for intel version. Workflow looks like:

mbrew search <package>
# if you find the package, install
mbrew install <package>
# if you don't find the package, search intel version
ibrew search <package>
# if you find the package, install
ibrew install <package>
# if you don't find it, you will have to build from source, or get some 
# pre-built binaries from the respective websites

Common Problems

There are some common problems while installing libraries with npm, yarn or pip that the package being installed needs to be built with node-gyp or make and the package being built does not build on arm, in such cases you want to invoke the package manager again as an intel program irun pip install <package>.

Note: You can always invoke the terminal itself as intel program and all subprocesses will be ran through rosetta and you may not get any problems, but I'd suggest you only use rosetta when you need to to reap all the performance benefits of m1.