How to set up homebrew and a python development environment on the new Apple M1 Macs.

I talk you through the process of how I set up homebrew, and my python development environment to actually work on an apple M1 mac.

3 minute read

31/12/2020

You have unwrapped that shiny new M1 mac, and after binge-watching Ted Lasso on the accompanying free year of Apple TV+, you're ready to do some actual work.

A few people have advised against buying one of the new M1 macs as a developer, and they're not entirely wrong. It's still pretty bleeding edge, and many tools have not been fully optimised to work on it.

Big Sur includes emulation software called Rosetta 2, which translates x86(Intel) based applications to work on the new arm CPUs in the M1 macs. We don't need to worry about the details, just know that with a little work, you can get your dev environment set up as it should be.

This article is for you (and me), and I am mostly putting all the steps I took to get set-up in one place. As I said, development is still very active on many tools, so most of these steps may very well become obsolete in a few months.

Pre Note

Before we start, install Xcode command line tools if you haven't already. The command is:

sh
xcode-select --install

First Step - Homebrew

Ahh Homebrew. It is one of those tools that once you get used to, you wonder how you ever used a mac without it. At the time of writing, brew isn't fully supported on the M1. They recommend that you run it via Rosetta 2, which means that you would be running the Intel version.

There's nothing wrong with that, but the mac is an arm mac, and you want arm stuff on your arm mac. First thing I did was install the arm version of brew.

They recommend that the arm version of brew is installed to a separate folder so as not to interfere with the Intel version. They knew you'd need both.

This script here, by this great youtuber, installs the arm version of brew to the correct folder and even goes further to add the right path exports to your .zshrc file.

To use his script, paste the following in your terminal and press enter.

sh
/bin/bash -c "$(curl -fsSL https://gist.githubusercontent.com/nrubin29/bea5aa83e8dfa91370fe83b62dad6dfa/raw/48f48f7fef21abb308e129a80b3214c2538fc611/homebrew_m1.sh)

You can leave it at that if you think you wouldn't need any Intel based tools. However, considering that the only python version compiled for arm at this moment is python 3.9, and you will not be able to get previous versions to even install properly at the moment, I recommend having both arm brew and Intel brew installed.

I develop desktop applications using python and pyqt, and package them for distribution using pyinstaller. I also use asdf to manage my installed python versions. The arm mac is currently allergic to this kind of development environment, and so (for now) everything should be run in emulation - 'iRosetta' takes care of that.

If you try to install the Intel brew using the curl command on brew.sh, it doesn't work, and I could have sworn my computer tried to punch me in the face. The solution is to prefix the command with arch -x86_64. So:

sh
arch -x86_64 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"

Then you'll have to install every package using:

sh
arch -x86_64 brew install <package>

I think better still, is to open your terminal using Rosetta 2 and run the command normally in that environment.

To make things easier, duplicate your terminal application of choice, and rename it to something that helps you differentiate them. I use iTerm2 as my terminal emulator, and I named the duplicate iRosettaTerm2 (super creative right?).

Right-click your duplicate, select get info and check Open using Rosetta. This means that every command run in this terminal will be translated by Rosetta, and Intel applications will be happy.

When you install brew using the curl command in this terminal, it works as normal and any brew commands you enter do not need to be prefixed as above.

Creating a separate terminal emulator for installing intel applications.

Side Note

If you have both arm brew and Intel brew installed, any terminal you use will use the brew that appears first on the path. So make sure your path export in your .zshrc file looks like this:

~/.zshrc
sh
export PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/homebrew/bin

To use Intel brew, and

~/.zshrc
sh
export PATH=/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

for arm brew. The difference is that the path to arm brew /opt/homebrew/bin appears first if you want to you arm brew, and last if you want Intel brew.

Next is Asdf

With everything emulated through rosetta, things should just work, right? Wrong.

Asdf kept failing at building python versions below 3.9.1.

Asdf-python uses pyenv under the hood, and pyenv requires zlib and bzip2, which are included in macOS by default. However, the versions on the new M1 macs are not compatible with pyenv as of now.

The fix for this is to reinstall these packages using Intel brew. Commands:

sh
brew reinstall zlib bzip2

You also need to add these exports in your .zshrc file.

~/.zshrc
sh
export LDFLAGS="-L/usr/local/opt/zlib/lib -L/usr/local/opt/bzip2/lib"
export CPPFLAGS="-I/usr/local/opt/zlib/include -I/usr/local/opt/bzip2/include"

Now when asdf tries to install python, it uses the ones in brew, and not the ones in xcode.

Good to Go

With the dev environment set up this way, python packages like numpy, pyqt, and matplotlib will work as expected, and you can get productive. I still have not been able to get pipenv to work properly, however virtualenv and virtualenvwrapper work as expected. Stay in and build, stay safe.

Speak soon.

Share this article:

Got a cool project in mind?

Lets work together.

Hit me up.

ProjectsBlogAboutContact
LinkedInTwitterGithubEmail
©2021 Dr. Abbas Egbeyemi. All rights reserved. Privacy Policy.