# Building CircuitPython

## Introduction

Adafruit [CircuitPython](../../../../welcome-to-circuitpython/) is an open-source implementation of Python for microcontrollers. It's derived from [MicroPython](https://micropython.org/), a ground-breaking implementation of Python for microcontrollers and constrained environments.

CircuitPython ships on many Adafruit products. We regularly create new releases and make it easy to update your installation with new builds.

However, you might want to build your own version of CircuitPython. You might want to keep up with development versions between releases, adapt it to your own hardware, add or subtract features, or add "frozen" modules to save RAM space. This guide explains how to build CircuitPython yourself.  
  
CircuitPython is meant to be built in a POSIX-style build environment. We'll talk about building it on Linux-style systems or on macOS. It's possible, but tricky, to build in other environments such as CygWin or MinGW: we may cover how to use these in the future.

# Building CircuitPython

## Linux Setup

## Set Up a Real or Virtual Linux Machine

If you don't already have a Linux machine, you can set one up in several different ways. You can install a Linux distribution natively, either on its own machine or as a dual-boot system. You can install Linux on a virtual machine on, say, a Windows host machine. You can also [use Windows Subsystem for Linux](../../../../building-circuitpython/windows-subsystem-for-linux) (WSL), available on Microsoft Windows 10 and 11. WSL allows you to run a Linux distribution with an emulation layer substituting for the Linux kernel.

We recommend using the&nbsp;[Ubuntu](https://ubuntu.com) distribution of Linux or one of its variants (Kubuntu, Mint, etc.). The instructions here assume you are using Ubuntu. The 24.04 LTS (Long Term Support) version is stable and reliable, but needs a Python **venv** setup,&nbsp;detailed on the [Build CircuitPython](https://learn.adafruit.com/building-circuitpython/build-circuitpython) page in this guide. Ubuntu 22.04 can also be used, but some of the tools are out of date. Use 24.04 if you can.

### Native Linux

You can install Ubuntu on a bare machine easily. Follow the [directions](https://ubuntu.com/tutorials/install-ubuntu-desktop) on the Ubuntu website. You can also install Ubuntu on a disk shared with your Windows installation, or on a separate disk, and make a dual-boot installation.

### Linux on a Virtual Machine

Linux can also be installed easily on a virtual machine. First you install the virtual machine software, and then create a new virtual machine, usually giving the VM software a .iso file of Ubuntu or another distribution. On Windows,&nbsp;[VM Workstation Player](https://www.vmware.com/products/workstation-player/workstation-player-evaluation.html) and [VirtualBox](https://www.virtualbox.org/) are both free and easily installed. Make your virtual machine filesystem at least 20GB-40GB so you won't run out of space.

### Raspberry Pi

Raspberry Pi OS is a Debian-based Linux distribution, like Ubuntu. Use the latest version of Raspberry Pi OS so that the tools are as up to date as possible. You can also install Ubuntu on your Raspberry Pi. You will need to download the **aarch64** executable for the **arm-none-eabi-gcc** toolchain. The RPis, particularly Pi 3 and earlier, are not fast machines: be prepared to wait a while for a build to complete.

## Install Build Tools on Ubuntu

The Ubuntu 24.04 and 22.04 LTS Desktop distributions include most of what you need to build CircuitPython. You'll need to install some additional packages, including **build-essential** , if it's not already installed, and also **git** , **git-lfs** , **gettext,** and **cmake**.

You also need the **uncrustify** tool if using pre-commit, but that will be installed later, when you install the Python dependencies, even though uncrustify is not a Python tool _per se_.

The version of **git** (2.30) installed with Ubuntu 22.04 will work, but git versions that support partial submodule cloning (2.36 or later) will work better with submodules. The standard version of git in Ubuntu 24.04 works fine.

To install these tools, in a terminal window, do:

```terminal
sudo apt update
# Try running `make`. If it's not installed, do:
# sudo apt install build-essential

# If you don't have add-apt-repository, do:
# sudo apt install software-properties-common

# Recommended on Ubuntu 22.04: use the latest stable version of git:
# Optional and not necessary on Ubuntu 24.04.
sudo add-apt-repository ppa:git-core/ppa

sudo apt install git git-lfs gettext cmake
```

### Cortex-M Builds

Most CircuitPython boards use an ARM Cortex-M processor.&nbsp; You need to download and unpack the appropriate ARM Cortex-M toolchain. Do not use the obsolete ARM Ubuntu "ppa" (private package archive). The links below point to the general download pages for the toolchains. Choose the **arm-none-eabi** version of the compiler, and select the correct architecture for your development computer, such as **x64 Linu** x for a typical Linux PC. The package library for your particular Linux distribution will not necessary install the correct version.

- For CIrcuitPython 9.x, use the [13.2.Rel1 version for](https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads)[AArch32 bare-metal target (arm-none-eabi)](https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads) on the Arm GNU Toolchain Downloads page. Scroll down to find the correct version.
- For CircuitPython 10.x use the [14.2.Rel1 version for](https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads)[AArch32 bare-metal target (arm-none-eabi)](https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads) on the Arm GNU Toolchain Downloads page. Scroll down to find the correct version. GCC 14 is required as of [PR #10386](https://github.com/adafruit/circuitpython/pull/10386), which is after 10.0.0-alpha.6.

If you want to build an older version of CircuitPython:

- For CircuitPython 6.1, 7.x, and 8.x, use the 10-2020-q4-major version on [this page](https://developer.arm.com/downloads/-/gnu-rm).
- For CircuitPython 5 and 6.0, use the 9-2019-q4-major version on [this page](https://developer.arm.com/downloads/-/gnu-rm).
- CircuitPython 4 was built with the 7-2018q2-update version on [this page](https://developer.arm.com/downloads/-/gnu-rm).

### Cortex-A Builds (Only for **broadcom** Port)

The **broadcom** port (Raspberry Pi Linux boards, _not_ Pi RP2040 or RP2350) needs a different toolchain. Use the&nbsp;Cortex-A toolchain:

- For CircuitPython 7.x, 8.x, and 9.x, use the [10.3-2021.07 version](https://developer.arm.com/downloads/-/gnu-a#panel1a).
- For CircuitPython 10.x, use the [13.3-Rel1 AArch64 bare-metal target (aarch64-none-elf)](https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads#panel2a).

You will also need the **mtools** package for Cortex-A:

```terminal
sudo apt install mtools
```

And finally, you need a version 4.2 or later of **mkfs.fat,** which is part of the **dosfstools** package. Ubuntu 20.04 has version 4.1. If you are still running 20.04. You can download and build dosfstools. After you do so, copy mkfs.fat to some place that is or will be on your&nbsp; **PATH**.

(This is not necessary on Ubuntu 22.04 or later.)

```terminal
wget https://github.com/dosfstools/dosfstools/releases/download/v4.2/dosfstools-4.2.tar.gz
tar xvf dosfstools-4.2.tar.gz
cd dosfstools-4.2
./configure
make
```

### Installing the Toolchain

Unpack the Cortex-M or Cortex-A toolchain in a convenient directory.

```terminal
# This is an example.
cd ~/bin
tar xvf &lt;name of the .bz2 or .xz file you downloaded&gt;
```

Next, add a line to your **.bash\_profile** or other startup file to add the unpacked toolchain executables to your **PATH**. For example:

```terminal
export PATH=/home/$USER/bin/arm-gnu-toolchain-13.2.Rel1-x86_64-arm-none-eabi/bin:$PATH
```

Open a new terminal window, and see if you now have the correct executables on your path:

```terminal
which arm-none-eabi-gcc
/home/halbert/bin/arm-gnu-toolchain-13.2.Rel1-x86_64-arm-none-eabi/bin/arm-none-eabi-gcc
```

### Other Builds

- For Espressif (ESP32-S2, -S3, -C3), see the [Espressif build page](https://learn.adafruit.com/building-circuitpython/esp32-s2-build).
- For Spresense (cxd56), see the [cxd56 README](https://github.com/adafruit/circuitpython/blob/main/ports/cxd56/README.md).
- For Litex (FOMU), see the [litex README](https://github.com/adafruit/circuitpython/blob/main/ports/litex/README.rst).

## Setting up a Python Virtual Environment (Ubuntu 24.04 and similar only)

On Ubuntu 24.04 and other recent Debian-derived Linux distribution releases, you can no longer install Python modules with **pip** without first setting up a Python virtual environment. You can override this restriction, but it has been set up as a safeguard. The guide&nbsp;[Python Virtual Environment Usage on Raspberry Pi](https://learn.adafruit.com/python-virtual-environment-usage-on-raspberry-pi) explains this in great detail, from the point of view of using Raspberry Pi OS.

For building CircuitPython, here is a short recipe. First, make sure that **venv** , the virtual environment module, is installed. Then create the virtual environment. Here we name it **.py** , but you can pick a different name.

```terminal
# Install if not already installed.
sudo apt install python3-venv

# Put the venv (virtual environment) in your home directory.
cd

# Create the venv and name it `.py` (or whatever you'd like).
python3 -mvenv .py
```

Once you create a virtual environment, you "activate" it by sourcing the **activate** script provided by the virtual environment. Note that you cannot just run the script. You have to source it into the current shell using the `source` or the `.` command:

```terminal
# Enable the virtual environment.
source .py/bin/activate
```

Your shell will probably show an indication that you are now using the Python virtual environment named **.py** :

```terminal
(.py) yourusername@yourmachine:~$
```

Now you are ready to start building. You'll install the Python modules you need while you are inside this virtual environment.

Note that if you're doing an Espressif build, it creates its own virtual environment when you run `esp-idf/export.sh`. So don't use the virtual environment you created above for those builds.

To leave the virtual environment, you deactivate it:

```terminal
deactivate
```

### Using the Virtual Environment Automatically

If it's convenient for you, you can activate the virtual environment in any new terminal by putting a line like this in your **.bashrc** , **.bash\_aliases** , or other shell startup file:

```terminal
source ~/.py/bin/activate
```

## Next Steps

Now move to the&nbsp;[Build CircuitPython](../../../../building-circuitpython/build-circuitpython) section of this guide. There we will get the CircuitPython source code, install a few more dependencies, and then build!

# Building CircuitPython

## macOS Setup

To build CircuitPython on macOS, you need to install **git** , **python3** , and the compiler toolchain. The easiest way to do this is to first install [Homebrew](https://brew.sh/), a software package manager for macOS. Follow the directions on its webpages.

Now install the software you need:

```terminal
brew update
brew install git git-lfs python3 gettext uncrustify cmake
brew link gettext --force
```

Then install the compiler toolchain. You may be able to use [the **gcc-arm-embedded** homebrew formula](https://formulae.brew.sh/cask/gcc-arm-embedded) to install the correct toolchain, but make sure you have **homebrew** install the correct version, as described on the [Linux Setup](https://learn.adafruit.com/building-circuitpython/linux) page in this guide. A version that is too old or too new may cause compilation errors.

As an alternative to&nbsp; **homebrew** , on the [Linux Setup](https://learn.adafruit.com/building-circuitpython/linux) page, you can find pointers to the download pages for different kinds of ARM processors, and also special instructions for other builds (not all are available on macOS). Download and install the appropiate **.pkg** file for your Mac.

Once the dependencies are installed, we'll also need to make a disk image to clone CircuitPython into. By default the macOS filesystem is case insensitive. In a few cases, this can confuse the build process. So, **we recommend** [creating](https://support.apple.com/guide/disk-utility/create-a-disk-image-dskutl11888/mac)[a case sensitive disk image with Disk Utility](https://support.apple.com/guide/disk-utility/create-a-disk-image-dskutl11888/mac) to store the source code. Make the image capable of storing at least 10GB, preferably 20GB, so you won't run out of space if you do extensive development. You can use a sparse bundle disk image which will grow as necessary, so you don't use up all the space at once. The disk image is a single file that can be mounted by double clicking it in the Finder. Once it's mounted, it works like a normal folder located under the **/Volumes** directory.

## Install `gmake` if Necessary

Depending on your version of macOS, whether or not you have installed Xcode, and other factors, the version of make on your Mac may not be recent enough to run builds. Check the version:

```terminal
make --version
# and
gmake --version
```

If neither program exists, or both are older than version 4.3, install a newer version of `gmake` with `brew`:

```terminal
brew install make
```

If you install the `brew` version of make, it will be known as `gmake`.

That's it! Now you can move on and actually [Build CircuitPython](../../../../building-circuitpython/build-circuitpython). There we will get the CircuitPython source code, install a few more dependencies, and then build!

# Building CircuitPython

## Windows Subsystem for Linux (WSL) Setup

Windows Subsystem for Linux (WSL) is a feature of Windows 10 and 11 that lets you run Ubuntu and other versions of Linux right in Windows. It's real Ubuntu, without the Linux kernel, but with all the software packages that don't need a graphical interface. You can build CircuitPython in WSL easily. It's easier to install than a Linux virtual machine.

## Install WSL

The installation procedures for WSL continue to evolve. Rather than provide information here which quickly becomes outdated, we ask that you refer to Microsoft's official instructions: [How to install Linux on Windows with WSL](https://learn.microsoft.com/en-us/windows/wsl/install). Enable WSL 2, which is better for our purposes than WSL 1 in several ways.

Note that your PC must have hardware virtualization support. Virtualization must also be enabled in the BIOS or UEFI on your motherboard.

One WSL 2 is set up, you need to choose a Linux distribution to install, as described in the document above. Choose Ubuntu 24.04 if you can.

## Finish Linux Install

Once WSL is set up, just proceed with the regular [Linux Setup](https://learn.adafruit.com/building-circuitpython/linux). You will install the Linux-based tools, not Windows-based tools

## Build CircuitPython

From this point on, you can build CircuitPython just as it's built in regular Ubuntu, described in the&nbsp;[Build CircuitPython](../../../../building-circuitpython/build-circuitpython) section of this guide.

## Moving Files to Windows

You can copy files to and from Windows through the /mnt/c. For instance, if you want to copy a CircuitPython build to the desktop, do:

```terminal
cp build-circuitplayground_express/firmware.uf2 /mnt/c/Users/YourName/Desktop
```

Danger: Warning: Don't build in a shared folder (in `/mnt/c`). You'll probably have filename and line-ending problems.

You might be tempted to clone and build CircuitPython in a folder shared with the Windows filesystem (in **/mnt/c** somewhere). That can cause problems, especially if you use **git** commands on the Windows side in that folder. The CircuitPython build assumes case-sensitive filenames, but Windows usually ignores filename case differences. You may also have line-ending problems (CRLF vs.&nbsp; LF). It's better to clone and build inside your home directory in WSL, and copy files over to a shared folder as needed. It is possible to drag and drop files between WSL and Windows.

## Mounting a CircuitPython Board in WSL

You can mount your **...BOOT** or **CIRCUITPY** drive in WSL. Create a mount point and then mount it. Note that you'll have to remount each time the drive goes away, such as when you restart the board or switch between the **BOOT** drive and **CIRCUITPY**. So it's probably more convenient to copy files to the board from Windows instead of WSL.

```terminal
# You only need to do this once.

# Choose the appropriate drive letter.
sudo mkdir /mnt/d

# Now mount the drive.
sudo mount -t drvfs D: /mnt/d

# Now you can look at the contents, copy things, etc.
ls /mnt/d
cp firmware.bin /mnt/d
# etc.
```

## Editing Files in WSL

You can use the usual Linux editors in WSL, such as **vim** and **emacs**. You may need to install them explicitly. Visual Studio Code (not Visual Studio) is also available: do a websearch to find the latest instructions. Visual Studio Code in Windows has an extension that supports WSL.

# Building CircuitPython

## Manual Setup

If the setup instructions above don't work for your particular OS setup, for whatever reason, you can get the ball rolling by installing these tools in whatever way you can and then getting them to work with the **Makefile** in&nbsp; **circuitpython/ports/atmel-samd**. ( **main** branch):

- **git**
- **git-lfs**
- **make**
- **python3**
- **gettext**
- **cmake**
- All Python packages listed in **requirements-dev.txt**. You will need to clone the repository to see that file.
- ARM gcc toolchain for Cortex-M boards: [https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads](https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads)
- ARM gcc toolchain for Cortex-A boards (only needed for `broadcom` port): [https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-a/downloads](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-a/downloads)  
See information about which gcc version to pick on the [Linux Setup page](https://learn.adafruit.com/building-circuitpython/linux#install-build-tools-on-ubuntu-2986713-2) of this guide.

# Building CircuitPython

## GitHub Codespaces

GitHub Codespaces provides a cloud-based development environment which you can use instead of creating and maintaining a local development environment. There is a free tier that should be sufficient for casual CircuitPython development.

GitHub user [@bablokb](https://github.com/bablokb) has set up and plans to maintain GitHub Codespaces "devcontainers" for the different CIrcuitPython port builds. For more information, see [Using Github Codespaces for CircuitPython Development](https://adafruit-playground.com/u/picofun/pages/using-github-codespaces-for-circuitpython-development)&nbsp;in the [Adafruit Playground](https://adafruit-playground.com/). Thank you, @bablokb!

# Building CircuitPython

## Recent Changes

The build setup and steps in this guide change frequently, and are updated as needed. If you are are having trouble, check this page, which highlights recent changes, to see if you need to update your build environment. The changes mentioned here are also documented in the other pages in this guide.

# Install **git-lfs**

**git-lfs** is now a required prerequisite, as of CircuitPython 8.1.0. The submodules in the `silabs` port require it.

# Fetching Submodules

Submodules should be fetched using the Makefile targets `fetch-all-submodules`,&nbsp; which is in the top-level **Makefile** , or `fetch-port-submodules`, which is used from port-specific Makefiles. If you use standard git commands for fetching submodules, you will end up fetching many gigabytes of unnecessary versions.

See [this page section](https://learn.adafruit.com/building-circuitpython/build-circuitpython#fetch-submodules-3141425) for more details.

These make targets do either a partial "blobless" clone of all submodules, if your version of **git** supports it, or else does a shallow depth 1 clone.

`make remove-all-submodules` removes all submodules and cleans up, so you can do a fresh `make fetch-all-submodules`&nbsp;or `fetch-port-submodules`. Use `make remove-all-submodules` if you are getting errors when fetching submodules.

These Makefile targets were added June 6, 2023, changing a previous target, added in late March, 2023 that only fetched all modules, `make fetch-submodules`.

# Building CircuitPython

## Build CircuitPython

Info: If you are building  for an Espressif board, read this section and also read the [Espressif Builds](https://learn.adafruit.com/building-circuitpython/espressif-build) page in this guide for additional instructions.

## Fetch the Code to Build

Once your build tools are installed, fetch the CircuitPython source code from its GitHub repository ("repo") and also fetch the git "submodules" it needs. The submodules are extra code that you need that's stored in other repos.

Info: Fork the `adafruit` repo if you plan to submit pull requests back to `circuitpython`

In the commands below, you're cloning from Adafruit's CircuitPython repo. But if you want to make changes, you might want to "fork" that repo on GitHub to make a copy for yourself, and clone from there. For more information about using GitHub and forking a repo, see the [Contribute to CircuitPython with Git and GitHub](https://learn.adafruit.com/contribute-to-circuitpython-with-git-and-github/) guide.

Info: If you are on macOS and you had to install the **brew** version of **make**, use **gmake** in all examples below instead of **make**.

```terminal
git clone https://github.com/adafruit/circuitpython.git
cd circuitpython
```

## Install Required Python Packages

After you have cloned the repo, you'll need to install some Python packages that are needed for the build process. You only need to do this the first time, though you may want to run this again from time to time to make sure the packages are up to date.

```terminal
# Install pip if it is not already installed (Linux only). Try running pip first.
sudo apt install python3-pip

# Install needed Python packages from pypi.org.
pip3 install --upgrade -r requirements-dev.txt
pip3 install --upgrade -r requirements-doc.txt
```

The `--upgrade` flag will force installation of the latest packages, except where a version is explicitly specified in the **requirements-\*.txt** files.

If you get an error indicating that `rust` is needed to install `minify-html`, install `rust`:

```terminal
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# You can verify the installation by running:

source $HOME/.cargo/env #Import the environment config for rust
rustc --version
```

## Checking out a Specific Branch or Version

If you want to build a version other the latest, checkout the branch or tag you want to build. For example:

```terminal
# Build using the latest code on the main branch.
git checkout main

# Build the latest code on the 9.0.x branch
git checkout 9.0.x

# Build the 9.2.1 version exactly.
git checkout 9.2.1
```

Note the build process has evolved, and earlier versions will need to be built somewhat differently than how the instructions in this guide specify. If you have trouble, ask on [Discord](https://adafru.it/discord) or the [forums](https://forums.adafruit.com).

## Fetch Submodules

We are not using `git submodule update --init --recursive` or `git submodule update --init`. Instead you run the special **Makefile** target `make fetch-all-submodules` at the top level, or `make fetch-port-submodules` when you in a particular **ports/_port-name_** directory. The target fetches only as many commits from each submodule as is necessary, using either a blobless partial clone (if available) or a shallow clone. This avoids downloading the complete trees of some large submodules, saving time and space.

`make fetch-all-submodules` fetches all the submodules in the entire repository, and can take several minutes and use up a lot of storage. If you are planning to build only in one or a few port directories, you'll save time by using `make fetch-port-submodules`, which fetches only the submodules need for that particular port.

If you are having trouble with your submodules, you can clean out all the fetched modules by doing `make remove-all-submodules` at the top level. Then run `make fetch-all-submodules` or `make fetch-port-submodules` again to fetch a fresh copy of all the submodules. (There is no `make remove-port-submodules`.)

### Using a Version of git that can do Partial Clones

As mentioned above, the submodule fetching targets try to do a blobless partial clone if possible. This is better than a shallow clone: it is slightly faster, and the partial clone acts like a full clone if you want to maneuver around in the submodule by checking out other commits, examining the history, etc.

Git version 2.36 or later supports blobless partial clones. Ubuntu 24.04 includes such a version. To find out which version of git you are using, do&nbsp;`git --version`. Consider installing a newer version of git if it is available. On earlier versions of Ubuntu, you can install the&nbsp;[git PPA](https://launchpad.net/~git-core/+archive/ubuntu/ppa) and get the latest stable version of git. On macOS, **homebrew** may provide a later version for you.

```terminal
cd circuitpython   # go to the top level
make fetch-all-submodules

# OR, for example, to fetch only the submodules needed for RP2040 builds:

cd circuitpython/ports/raspberrypi
make fetch-port-submodules
```

## Install **pre-commit**

We are using the **pre-commit** system to check submitted code for problems before it gets to GitHub. For more information, see this [Learn Guide page](https://learn.adafruit.com/creating-and-sharing-a-circuitpython-library/check-your-code). To add **pre-commit** to your repository clone, do:

```terminal
cd &lt;your repository clone directory&gt;
# You only need to do this once in each clone.
pre-commit install
```

Info: Are you seeing errors when pre-commit runs? See [this hint](https://learn.adafruit.com/creating-and-sharing-a-circuitpython-library/check-your-code#workaround-for-pre-commit-issues-on-ubuntu-and-debian-3086216).

## Build **mpy-cross**

Build the **mpy-cross** compiler first, which compiles Circuitpython **.py** files into **.mpy** files. It's needed to include library code in builds that use [frozen modules](https://learn.adafruit.com/building-circuitpython/adding-frozen-modules).

(If you get a **make: msgfmt: Command not found** error, you have not installed **gettext**. Go back to the Setup page for your operating system.)

Normally you do not need to rebuild **mpy-cross** on every pull or merge from the `circuitpython` repository or for your own changes. The **.mpy** format does not change very often. But occasionally when we merge from MicroPython, the format changes. You will find that your old **.mpy** files or frozen libraries give an error, and you will need to rebuild **mpy-cross**.

```terminal
make -C mpy-cross
```

## Build CircuitPython

Now you're all set to build CircuitPython. If you're in the **main** branch of the repo, you'll be building the latest version. Choose which board you want to build for. The boards available are all the subdirectories in **ports/atmel-samd/boards/**.

```terminal
cd ports/atmel-samd
make BOARD=circuitplayground_express
```

By default the en\_US version will be built. To build for a different language supply a **TRANSLATION** argument.

```terminal
cd ports/atmel-samd
make BOARD=circuitplayground_express TRANSLATION=es
```

## Run Your Build!

When you've successfully built, you'll see output like:

```terminal
Create build-circuitplayground_express/firmware.bin
Create build-circuitplayground_express/firmware.uf2
python2 ../../tools/uf2/utils/uf2conv.py -b 0x2000 -c -o build-circuitplayground_express/firmware.uf2 build-circuitplayground_express/firmware.bin
Converting to uf2, output size: 485888, start address: 0x2000
Wrote 485888 bytes to build-circuitplayground_express/firmware.uf2.
```

Copy **firmware.uf2** to your board the same way you'd update CircuitPython: Double-click to get the **BOOT** drive, and then just copy the **.uf2** file:

```terminal
# Double-click the reset button, then:
cp build-circuitplayground_express/firmware.uf2 /media/yourname/CPLAYBOOT
```

The board will restart, and your build will start running.

If you're using a board without a UF2 bootloader, you'll need to use **bossac** and the **firmware.bin** file, not the **.uf2** `` file. Detailed instructions are [here](../../../../welcome-to-circuitpython?view=all#flashing-with-bossac-for-non-express-feather-m0-s-and-arduino-zero).

## Use All Your CPUs When Building
Most modern computers have CPU chips with multiple cores. For instance, you may have a 2-core, 4-core, or 6-core or more CPU. Your CPU may also allow 2 "threads" per core, so that it appears to have even more cores. You can run much of the build in parallel by using the `make -j` flag. This is will speed up the build noticeably.

If you don't know how many cores or threads your CPU has, on Linux you can use this command:

```terminal
getconf _NPROCESSORS_ONLN
12
# This CPU has 6 cores and 12 threads.
```

Then, when you run make, add the -j\<n\> option to use as many cores or threads as possible. For example:

```terminal
make -j12 BOARD=trinket_m0
```

## When to `make clean`

After you make changes to code, normally just doing&nbsp;`make BOARD=...` will be sufficient. The changed files will be recompiled and CircuitPython will be rebuilt.

However, there are some circumstance where you must do:

```terminal
make clean BOARD=...
```

If you have changed the `#include` file structure in certain ways, if you have defined QSTR's (a way of defining constants strings in the CircuitPython source), or if you have added new error messages, then you must&nbsp;`make clean` before rebuilding. If you're not sure, it's always safe to `make clean` and then `make`. It might take a little longer to build, but you'll be sure it was rebuilt properly.

## Updating Your Repo

When there are changes in the GitHub repo, you might want to fetch those and then rebuild. Just "pull" the new code (assuming you haven't made changes yourself), update the submodules if necessary, and rebuild:

```terminal
git pull
 # only if necessary, from the top level directory
make fetch-submodules
# Then make again.
```

Those are the basics. There's a lot more to know about how to keep your forked repo up to date, merge "upstream" (Adafruit's) changes into your code, etc. We cover this in the [Contribute to CircuitPython with Git and GitHub](https://learn.adafruit.com/contribute-to-circuitpython-with-git-and-github) guide

# Building CircuitPython

## Adding Frozen Modules

Normally, all imported Python modules in CircuitPython are loaded into RAM in compiled form, whether they start as `.mpy` or `.py` files. Especially on M0 boards, a user program can run out of RAM if too much code needs to be loaded.

To ameliorate this problem, a CircuitPython image can include compiled Python code that is stored in the image, in flash memory, and executed directly from there. These are "internal frozen modules". The `circuitplayground_express` &nbsp;builds use this technique, for example.

If you would like to build a custom image that includes some frozen modules, you can imitate how it's done in the `circuitplayground_express` build. Look at `boards/circuit_playground_express/mpconfigboard.mk`:

https://github.com/adafruit/circuitpython/blob/master/ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.mk

Notice the `FROZEN_MPY_DIRS` lines in the file. Pick the **mpconfigboard.mk** file for the board you are using, and add one or more similar lines. You will need to do add directories for the libraries you want to include. If these are existing libraries in GitHub, you can add them as submodules. For instance, suppose you want to add the **Adafruit\_CircuitPython\_HID** library to the **feather\_m0\_express** build. Add this line to **boards/feather\_m0\_express/mpconfigboard.mk** :

```
FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_HID
```

Then add the library as a submodule:

```terminal
cd circuitpython/frozen
git submodule add https://github.com/adafruit/Adafruit_CircuitPython_HID
```

When you add the submodule it will be cloned into the **frozen/** directory.

**Set the submodule to a commit that is a release tag. If you try to freeze a module that is at untagged commit, you'll get a git error when building.** You can update all the frozen modules to the latest release tags by doing this, at the top level of your repository clone:

```terminal
make update-frozen-libraries
```

Alternatively, simply check out a tagged version of the submodule after you add the submodule and before you commit it:

```terminal
cd circuitpython/frozen/The_Module_to_Freeze   # example submodule name
git checkout 2.11.0   # example version number
```

Note that there is limited unused space available in the images, especially in the non-Express M0 builds, and you may not be able to fit all the libraries you want to freeze. You can of course try to simplify the library code if necessary to make it fit.

# Building CircuitPython

## Choosing a Different SPI Flash Chip

CircuitPython supports external SPI/QSPI flash chips for the CIRCUITPY filesystem. Each board build is setup to support only one or a few flash chips. The chips are not identical in how they are accessed, so you can't just substitute without rebuilding. The chips that CircuitPython currently supports are listed in a GitHub repository of chip data, [https://github.com/adafruit/nvm.toml](https://github.com/adafruit/nvm.toml),&nbsp;along with the settings needed for each.  
  
The chip(s) that are supported in a particular board are specified in the **mpconfigboard.mk** `` file for that board, in the line that defines `EXTERNAL_FLASH_DEVICES`.&nbsp; So change or add to `EXTERNAL_FLASH_DEVICES` if you want to use a different supported chip. We don't support a entire list of chips for each build because the table of data for all possible chips would take significant space in the CircuitPython build.

Here's an example:

```cpp
EXTERNAL_FLASH_DEVICES = "S25FL116K, S25FL216K, GD25Q16C"
```

# Building CircuitPython

## Customizing Included Modules

You may want to include a particular module that is not included by default for the board for your board. You can customize which modules to include in your CircuitPython build by adding or changing settings in the **mpconfigboard.mk** file for your board.

For example, here is the standard **circuitpython/ports/atmel-samd/boards/trinket\_m0/mpconfigboard.mk file:**

```cpp
USB_VID = 0x239A
USB_PID = 0x801F
USB_PRODUCT = "Trinket M0"
USB_MANUFACTURER = "Adafruit Industries LLC"

CHIP_VARIANT = SAMD21E18A
CHIP_FAMILY = samd21

INTERNAL_FLASH_FILESYSTEM = 1
LONGINT_IMPL = NONE
CIRCUITPY_FULL_BUILD = 0
```

Suppose you wanted to turn on `pulseio`, but you did not need MIDI support. There is not enough room for `pulseio` in this build, but if you turn other modules, you can make room. Sometimes this will work only for certain languages due to the size of the translation. In this case, for the `en_US` translation, turning off `usb_midi` frees up enough space to include `pulseio`. Add these lines to the file above:

```auto
CIRCUITPY_PULSEIO = 1
CIRCUITPY_USB_MIDI = 0
```

You can figure out which modules are on or off by looking at the [module support matrix in the CIrcuitPython documentation](https://circuitpython.readthedocs.io/en/latest/shared-bindings/support_matrix.html). It also helps to study the files **circuitpython/py/circuitpy\_mpconfig.mk** and **circuitpympconfig.h, and circuitpython/ports/\<your-board's-port\>/mpconfigport.mk** and **mpconfigport.h**.

 **Warning:** Don't put Makefile comments on the same line as Makefile assignments. I causes the variable value to [include the trailing spaces before comment character](https://stackoverflow.com/questions/9953825/trailing-comments-after-variable-assignment-subvert-comparison).&nbsp;

# Building CircuitPython

## Espressif Builds

The **ports/espressif** build setup is a rather involved process.&nbsp;Start with the setup described on the [Build CircuitPython](https://learn.adafruit.com/building-circuitpython/build-circuitpython) page. Don't forget to `make fetch-port-submodules` in **ports/espressif** or `make-fetch-all-submodules` at the top level.

### Linux

On Linux you probably need to install&nbsp; **ninja-build** and **cmake**.

```terminal
sudo apt install ninja-build cmake
```

The ESP-IDF expects there to be a **python** command which runs **python3**. On Ubuntu, there is no plain **python** by default, so install this simple package which links **python** to **python3**.

```terminal
sudo apt install python-is-python3
```

### macOS

On macOS, you will need to install **cmake** and **ninja:**

```terminal
brew install cmake
brew install ninja
```

### Run the ESP-IDF Installation Script Once

Once you have the prerequisites installed, change to the&nbsp; **ports/espressif** directory, and run the **esp-idf/install.sh** script. You only need to do this once: **install.sh** downloads the toolchains and other files it needs, and copies a number of files into **~/.espressif**. (If the ESP-IDF version used by CircuitPython changes, you will need to run **install.sh** again.)

**install.sh** also sets up a Python venv (virtual environment) in&nbsp; **~/.espressif/python-dev**. If you are already using a venv, maybe because you're using a recent version of Linux, you'll need to `deactivate` that venv before running **install.sh**. Otherwise you'll get an error that you can't create a venv inside another venv.

```terminal
cd circuitpython/ports/espressif

# If you are already inside a Python venv, deactivate it.
deactivate

esp-idf/install.sh
```

### Install Python Packages in the ESP-IDF venv

After running&nbsp; **export.sh** , you need to repeat the `pip3 install` commands described [here](https://learn.adafruit.com/building-circuitpython/build-circuitpython#install-required-python-packages-3086211) so that they take effect inside the Python environment set up by `source esp-idf/export.sh`. But you will need to do this only once.

```terminal
# Install needed Python packages from pypi.org after running install.sh or if the needed packages change.
pip3 install --upgrade -r requirements-dev.txt
pip3 install --upgrade -r requirements-doc.txt
```

### Setting Up the ESP-IDF Environment Before Building

You only need to run **esp-idf/install.sh** once. But later, in each fresh terminal window in which you are doing builds, you need to run **esp-idf/export.sh** in order to set up the correct **PATH** and other environment variables.

As with **install.sh** , if you're inside a Python venv, you need to deactivate it, so that **export.sh** can activate its own venv . Otherwise you will get an error that you can't create venv inside another venv.

```terminal
# Do this in each new terminal.
cd circuitpython/ports/espressif

# If you are inside a Python venv, deactivate it.
deactivate

source esp-idf/export.sh
```

 **export.sh** will suggest that you use **idf.py** to do a build after you run it. But we don't use **idf.py**. Instead, use `make`. For example:

```terminal
make BOARD=adafruit_magtag_2.9_grayscale
```

## Files Generated by a Build

`make BOARD=...` generates several files:

- **circuitpython-firmware.bin**
- **firmware.uf2** (not generated on boards that don't support the UF2 bootloader)
- **firmware.bin**

The **circuitpython-firmware.bin** is an intermediate file that does not include the bootloader and partition table. Ignore it: do not flash it to the chip. Flash **&nbsp;firmware.bin** instead.

## Decoding a Crash Backtrace

If your Espressif build of CircuitPython crashes with a line that looks something like this, you can process this backtrace and get a symbolic backtrace.

```auto
Backtrace: 0x400e33fd:0x3ffb1090 0x40086755:0x3ffb10d0 0x40084025:0x3ffb1100 0x4008e75d:0x3ffb3b70 0x4008e7a5:0x3ffb3ba0 ...
```

Run this python script, substituting the `BOARD` name for `<board>` below. Then paste the `Backtrace: ...` line into the `?` prompt. The script will look in the `build-<board>` directory, and use the **.elf** file there to decode the hex numbers in the backtrace.

&nbsp;

```terminal
$ cd ports/espressif
$ python3 tools/decode_backtrace.py &lt;board&gt;
```

# Building CircuitPython

## How to Add a New Board to CircuitPython


## Featured Products

### Adafruit Metro M4 feat. Microchip ATSAMD51

[Adafruit Metro M4 feat. Microchip ATSAMD51](https://www.adafruit.com/product/3382)
Are you ready? Really ready? Cause here comes the fastest, most powerful Metro ever. The **Adafruit Metro M4** featuring the **Microchip ATSAMD51**. This Metro is like a bullet train, with its 120MHz Cortex M4 with floating point support. Your code will zig and zag...

In Stock
[Buy Now](https://www.adafruit.com/product/3382)
[Related Guides to the Product](https://learn.adafruit.com/products/3382/guides)
### Adafruit METRO M0 Express - designed for CircuitPython

[Adafruit METRO M0 Express - designed for CircuitPython](https://www.adafruit.com/product/3505)
Metro is our series of microcontroller boards for use with the Arduino IDE. This new **Metro M0 Express** board looks a whole lot like our&nbsp;[original Metro 328](https://www.adafruit.com/product/2488), but with a huge upgrade. Instead of the ATmega328, this Metro...

In Stock
[Buy Now](https://www.adafruit.com/product/3505)
[Related Guides to the Product](https://learn.adafruit.com/products/3505/guides)
### Adafruit Feather M0 Express

[Adafruit Feather M0 Express](https://www.adafruit.com/product/3403)
At the Feather M0's heart is an ATSAMD21G18 ARM Cortex M0+ processor, clocked at 48 MHz and at 3.3V logic, the same one used in the new&nbsp;[Arduino Zero](https://www.adafruit.com/products/2843). This chip has a whopping 256K of FLASH (8x more than the Atmega328 or 32u4) and...

Out of Stock
[Buy Now](https://www.adafruit.com/product/3403)
[Related Guides to the Product](https://learn.adafruit.com/products/3403/guides)
### Circuit Playground Express

[Circuit Playground Express](https://www.adafruit.com/product/3333)
 **Circuit Playground Express** is the next step towards a perfect introduction to electronics and programming. We've taken the original Circuit Playground Classic and made it even better! Not only did we pack even more sensors in, we also made it even easier to...

In Stock
[Buy Now](https://www.adafruit.com/product/3333)
[Related Guides to the Product](https://learn.adafruit.com/products/3333/guides)
### Adafruit ItsyBitsy M0 Express - for CircuitPython & Arduino IDE

[Adafruit ItsyBitsy M0 Express - for CircuitPython & Arduino IDE](https://www.adafruit.com/product/3727)
What's smaller than a Feather but larger than a Trinket? It's an **Adafruit ItsyBitsy M0 Express**! Small, powerful, with a rockin' ATSAMD21 Cortex M0 processor running at 48 MHz - this microcontroller board is perfect when you want something very compact, but still...

In Stock
[Buy Now](https://www.adafruit.com/product/3727)
[Related Guides to the Product](https://learn.adafruit.com/products/3727/guides)
### Adafruit GEMMA M0 - Miniature wearable electronic platform

[Adafruit GEMMA M0 - Miniature wearable electronic platform](https://www.adafruit.com/product/3501)
The **Adafruit Gemma M0** is a super small microcontroller board, with just enough built-in to create many simple projects. It may look small and cute: round, about the size of a quarter, with friendly alligator-clip sew pads. But do not be fooled! The Gemma M0 is incredibly...

In Stock
[Buy Now](https://www.adafruit.com/product/3501)
[Related Guides to the Product](https://learn.adafruit.com/products/3501/guides)
### Adafruit Trinket M0 - for use with CircuitPython & Arduino IDE

[Adafruit Trinket M0 - for use with CircuitPython & Arduino IDE](https://www.adafruit.com/product/3500)
The&nbsp;Adafruit Trinket M0 may be small, but do not be fooled by its size! It's a tiny microcontroller board, built around the Atmel ATSAMD21, a little chip with _a lot_ of power. We wanted to design a microcontroller board that was small enough to fit into any project, and low...

Out of Stock
[Buy Now](https://www.adafruit.com/product/3500)
[Related Guides to the Product](https://learn.adafruit.com/products/3500/guides)
### Adafruit Feather HUZZAH with ESP8266 - Loose Headers

[Adafruit Feather HUZZAH with ESP8266 - Loose Headers](https://www.adafruit.com/product/2821)
Feather is the new development board from Adafruit, and like its namesake, it is thin, light, and lets you fly! We designed Feather to be a new standard for portable microcontroller cores.

This is the&nbsp; **Adafruit Feather HUZZAH ESP8266** &nbsp;- our take on an...

Out of Stock
[Buy Now](https://www.adafruit.com/product/2821)
[Related Guides to the Product](https://learn.adafruit.com/products/2821/guides)

## Related Guides

- [Adafruit Feather HUZZAH ESP8266](https://learn.adafruit.com/adafruit-feather-huzzah-esp8266.md)
- [Adafruit Feather M0 Express](https://learn.adafruit.com/adafruit-feather-m0-express-designed-for-circuit-python-circuitpython.md)
- [Adafruit Metro M0 Express](https://learn.adafruit.com/adafruit-metro-m0-express.md)
- [Adafruit Trinket M0](https://learn.adafruit.com/adafruit-trinket-m0-circuitpython-arduino.md)
- [Adafruit Circuit Playground Express](https://learn.adafruit.com/adafruit-circuit-playground-express.md)
- [Adafruit Metro M4 Express featuring ATSAMD51](https://learn.adafruit.com/adafruit-metro-m4-express-featuring-atsamd51.md)
- [Introducing ItsyBitsy M0 Express](https://learn.adafruit.com/introducing-itsy-bitsy-m0.md)
- [Machine Learning with Marshmallows and Tiny Sorter](https://learn.adafruit.com/machine-learning-with-marshmallows-and-tiny-sorter.md)
- [Circuit Playground or Hallowing Jack-o'-Lantern](https://learn.adafruit.com/circuit-playground-jack-o-lantern.md)
- [CircuitPython Hardware: PCA9685 PWM & Servo Driver](https://learn.adafruit.com/micropython-hardware-pca9685-pwm-and-servo-driver.md)
- [DAC Hacks for Circuit Playground Express & other ATSAMD21 Boards](https://learn.adafruit.com/circuit-playground-express-dac-hacks.md)
- [Which CircuitPython Board is Right for You?](https://learn.adafruit.com/choose-your-circuitpython-board.md)
- [Spy Theme Playback Device](https://learn.adafruit.com/spy-theme-playback-device.md)
- [How to Program SAMD Bootloaders](https://learn.adafruit.com/how-to-program-samd-bootloaders.md)
- [Cyber Flower: Digital Valentine](https://learn.adafruit.com/cyber-flower-digital-valentine.md)
- [Crickit Carnival Bumper Bot](https://learn.adafruit.com/crickit-carnival-bumper-car-bot.md)
- [Flapping Halloween Vampire Bat](https://learn.adafruit.com/flapping-halloween-vampire-bat.md)
- [3D Printed LED Fire Horns](https://learn.adafruit.com/3d-printed-led-fire-horns.md)
- [Getting Started With Steven Universe](https://learn.adafruit.com/getting-started-with-steven-universe.md)
- [CPU Temperature Logging with CircuitPython](https://learn.adafruit.com/cpu-temperature-logging-with-circuit-python.md)
- [Installing CircuitPython on SAMD21 Boards](https://learn.adafruit.com/installing-circuitpython-on-samd21-boards.md)
- [Mu Keyboard Shortcut Cheat Sheets](https://learn.adafruit.com/mu-keyboard-shortcut-cheat-sheets.md)
