Compiling ngspice for macOS on Apple Silicon
ngspice is the circuit simulator behind most open-source analog flows. Recently, I’ve been trying to set such a flow up on an Apple silicon laptop. Getting ngspice running was the first step in getting such a flow up and running on macOS.
The least resistance path to get ngspice working on macOS is brew install ngspice. However, the version shipped lags ngspice releases and lacks certain features such as OSDI support for Verilog-A models and OpenMP support for multi-threaded operation.
This article walks through the steps for compiling ngspice from source on Apple Silicon, the dependencies and the ./configure options worth knowing about. This has been tested with ngspice-46 on macOS Tahoe 26.5.1 on a MacBook Pro with the M4 Pro chip.
Prerequisites
The first prerequisite is that the Xcode command line tools are installed. This is where we get clang, make and header files. Make sure you have run xcode-select --install first if you haven’t already.
Next, Homebrew needs to be in place. We’re going to use it to get a bunch of libraries the ngspice build depends on. You can install it by using the bootstrap script /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)". The rest of the instructions here assume that Homebrew is installed under its default path for Apple Silicon of /opt/homebrew.
Installing build dependencies
brew install bison flex readline ncurses libomp
brew install --cask xquartz
flex/bison are the lexer/parser combination required for ngspice’s grammar engine. The libraries shipped by macOS are too old, and we get the new ones from homebrew. readline and ncurses are required to handle the interactive command line and terminal interactions. libomp is the OpenMP runtime, and is required for multi-core operation.
xquartz is the big one amongst these. It’s a pre-built cask, providing the X11 runtime and installs to /opt/X11. It’s required to build ngspice with the --with-x configuration that enables the internal waveform viewer. It’s entirely possible to skip this (and freetype which enables font rendering for X11) if you intend to use ngspice only in batch mode.
If you ever want to install directly from the git repository, you’ll also need the following additional packages.
brew install autoconf automake libtool
Getting the ngspice source
You can download ngspice from its SourceForge repository.
curl -L -o ngspice-46.tar.gz "https://sourceforge.net/projects/ngspice/files/ng-spice-rework/46/ngspice-46.tar.gz/download"
tar xzf ngspice-46.tar.gz && cd ngspice-46
Configuring the build
The first step in configuring is to set the environment variables for the compiler and linker flags so they refer to the dependencies we just installed. Homebrew packages aren’t on the default compiler search path, so CPPFLAGS/LDFLAGS point clang at them and PATH makes sure the right flex/bison executables run first.
export PATH="/opt/homebrew/opt/bison/bin:/opt/homebrew/opt/flex/bin:$PATH"
export CPPFLAGS="-I/opt/homebrew/opt/readline/include -I/opt/homebrew/opt/ncurses/include -I/opt/homebrew/opt/libomp/include -I/opt/X11/include/freetype2"
export LDFLAGS="-L/opt/homebrew/opt/libomp/lib -lomp -L/opt/homebrew/opt/readline/lib -L/opt/homebrew/opt/ncurses/lib -L/opt/X11/lib"
The tarball used comes with a pre-made ./configure, so we do not need to use autogen.sh like we would if we were building directly from the repository. There are a few different options for the ngspice configuration:
--with-x- builds the X11 waveform viewer. Good for observing simulation results directly from the interactive shell--enable-xspice- enables the XSPICE extension: event-driven/mixed-signal simulation and code-model plugin system--enable-cider- enables the CIDER extension: a coupled numerical device simulator, allowing the simulation of critical devices using physical/numerical models--enable-osdi- enables the OSDI loader, an interface to load in Verilog-A compiled models at runtime--enable-predictor- enables the predictor algorithm that estimates the next time-step’s solution to speed up transient simulation--enable-pss- enables periodic steady-state analysis--enable-openmp- enables OpenMP multi-threading for parallel matrix/device evaluation--with-readline=yes- uses GNU readline for command-line history and line editing in the interactive shell--disable-debugandCFLAGS="-O2"- drops debug symbols for a faster optimized build and sets the compiler optimization level to the standard-O2
./configure \
--with-x \
--enable-xspice \
--enable-cider \
--enable-osdi \
--enable-predictor \
--enable-pss \
--with-readline=yes \
--enable-openmp \
--disable-debug \
--prefix="/opt/ngspice" \
CFLAGS="-O2"
If you’d like to install it under a different directory than the specified /opt/ngspice/ you can change the prefix option.
./configure \
...
--prefix="$HOME/.local/ngspice" \
...
Compiling and installing
After configuring, you can compile ngspice (in parallel) by:
make -j$(sysctl -n hw.ncpu)
You can then install it into the prefix location by:
sudo make install
The sudo will only be required if you’re installing in a system area.
Make sure that the installation directory is in your path:
export PATH="$PATH:/opt/ngspice/bin"
Verifying the installation
Run ngspice --version and you should see:
➜ ~ ngspice --version
******
** ngspice-46 : Circuit level simulation program
** Compiled with KLU Direct Linear Solver
** The U. C. Berkeley CAD Group
** Copyright 1985-1994, Regents of the University of California.
** Copyright 2001-2025, The ngspice team.
** Please get your ngspice manual from https://ngspice.sourceforge.io/docs.html
** Please file your bug-reports at http://ngspice.sourceforge.net/bugrep.html
******
Better yet, you can launch ngspice and use the version -f command inside the ngspice shell to display the extensions:
ngspice 1 -> version -f
******
** ngspice-46 : Circuit level simulation program
** Compiled with KLU Direct Linear Solver
** The U. C. Berkeley CAD Group
** Copyright 1985-1994, Regents of the University of California.
** Copyright 2001-2025, The ngspice team.
** Please get your ngspice manual from https://ngspice.sourceforge.io/docs.html
** Please file your bug-reports at http://ngspice.sourceforge.net/bugrep.html
**
** CIDER 1.b1 (CODECS simulator) included
** XSPICE extensions included
** Relevant compilation options (refer to user's manual):
** OpenMP multithreading for BSIM3, BSIM4 enabled
** --enable-predictor
**
******
Wrapping up
With that, you have a feature-complete ngspice built from source — OSDI, OpenMP, XSPICE and the X11 viewer all compiled in, none of which Homebrew gives you. This is the engine the rest of the flow plugs into: OSDI lets you load Verilog-A compact models (compiled with OpenVAF), OpenMP puts the extra cores to work, and the interactive viewer gives you a quick look at results without leaving the shell. I’ll try to cover most of these in a follow-up post.