Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
110093e
Add job for Apple Silicon MacOS build
BatmanAoD Nov 27, 2023
6522083
Merge branch 'rigetti:main' into patch-1
BatmanAoD Aug 11, 2026
07373f9
Claude gets it working, maybe
BatmanAoD Aug 11, 2026
32e3558
fix README notes on aarch64
BatmanAoD Aug 11, 2026
975064e
GHA fixes
BatmanAoD Aug 11, 2026
b659ea1
Drop Intel macOS support
BatmanAoD Aug 11, 2026
ff1fb63
small fixes
BatmanAoD Aug 11, 2026
50f53b9
feat!: build against modern sbcl-librarian
BatmanAoD Aug 11, 2026
95cdf17
build: update CI, packaging and examples for the new architecture
BatmanAoD Aug 11, 2026
a44a84e
fix: load OpenBLAS into the image before magicl picks a backend
BatmanAoD Aug 12, 2026
62959f2
ci: fix the release/prerelease pipeline
BatmanAoD Aug 12, 2026
b163826
fix: check for BLAS and LAPACK, and install without sudo when already…
BatmanAoD Aug 12, 2026
7db4bfd
chore: prepare release 0.4.0-rc.0
BatmanAoD Aug 13, 2026
b151096
chore: address PR #58 review comments
BatmanAoD Aug 20, 2026
0dce152
build: depend on magicl with backend selection, drop the OpenBLAS wor…
BatmanAoD Aug 21, 2026
cf81306
refactor: use quilc's PROCESS-PROTOQUIL instead of vendoring it
BatmanAoD Aug 22, 2026
ca3cb70
chore: tag each upstream branch pin with its tracking issue
BatmanAoD Aug 22, 2026
0e87941
build: move the qvm pin to the current head of master
BatmanAoD Aug 22, 2026
c106be1
chore: cite quil-lang/qvm#330 where the qvm sha is pinned
BatmanAoD Aug 22, 2026
9799967
docs: cut PR-58-REVIEW-ANSWERS down to status and a draft comment
BatmanAoD Aug 22, 2026
cfe9249
docs: write the README for a newcomer, not for existing users
BatmanAoD Aug 26, 2026
add61fd
docs: record that CI is green on both platforms
BatmanAoD Aug 26, 2026
c59f4a2
fix: say what the SUDO_USER guard in install.sh actually checks
BatmanAoD Aug 26, 2026
60c0169
comment-tweaks
BatmanAoD Aug 26, 2026
122c4cf
refactor: express the compile_protoquil out-parameter as a type
BatmanAoD Aug 26, 2026
c194f9d
feat: install to any prefix, and need root only when the prefix deman…
BatmanAoD Aug 26, 2026
3e8075e
feat: add `make install`, and document installing without root
BatmanAoD Aug 26, 2026
1a7f0fa
chore: prepare release 0.4.0-rc.1
BatmanAoD Aug 26, 2026
39ae846
refactor: state the artifact's file list once
BatmanAoD Aug 26, 2026
82d1833
build: assemble the release artifact in a script, and stop shipping a…
BatmanAoD Aug 26, 2026
dab314d
docs: remove stale docs, remove REARCHITECTURE doc (only needed for r…
BatmanAoD Aug 26, 2026
f99bf8c
slightly simplify clone-lisp-deps
BatmanAoD Aug 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 86 additions & 66 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,143 +4,160 @@ on:
pull_request:
workflow_call:

env:
# SBCL is built from source for its linkable runtime; see scripts/install-sbcl.sh.
SBCL_VERSION: "2.6.7"
# Host used to cross-compile SBCL_VERSION on Linux. It cannot be apt's (22.04
# ships 2.1.11, too old) nor SBCL_VERSION's own binary release, which is linked
# against glibc 2.38 and will not run on 22.04. 2.5.0's binary needs only glibc
# 2.34 and is recent enough to build 2.6.7.
SBCL_BOOTSTRAP_VERSION: "2.5.0"
# libquil depends on three sbcl-librarian fixes (secondary-system FASL bundles,
# library prefix, configurable core name), which live on a branch of Rigetti's
# fork and are proposed upstream as quil-lang/sbcl-librarian#91.
SBCL_LIBRARIAN_REPO: "https://github.com/rigetti/sbcl-librarian.git" # TODO(rigetti/libquil#60)
SBCL_LIBRARIAN_REF: "fix-secondary-system-bundles" # TODO(rigetti/libquil#60)
# magicl selects a BLAS/LAPACK by searching a fixed list of paths. Until it
# knows about OpenBLAS, that search picks a backend that is wrong on arm64 and
# cannot be redirected without hacks -- so libquil had to preload OpenBLAS and
# symlink it over liblapack.dylib. This branch adds OpenBLAS to the search, a
# MAGICL_LAPACK_PATH override, and a startup check on what got loaded; it is
# proposed upstream as quil-lang/magicl#222.
MAGICL_REPO: "https://github.com/rigetti/magicl.git" # TODO(rigetti/libquil#62)
MAGICL_REF: "backend-selection-and-validation" # TODO(rigetti/libquil#62)
# PROCESS-PROTOQUIL lives in quilc's *application*, which libquil does not
# depend on, so libquil vendored a copy. quil-lang/quilc#933 moves it into the
# library and exports it, which is where it belongs.
QUILC_REPO: "https://github.com/rigetti/quilc.git" # TODO(rigetti/libquil#61)
QUILC_REF: "896-protoquil-transform" # TODO(rigetti/libquil#61)
# The Quicklisp dist supplying the Lisp dependencies.
QUICKLISP_VERSION: "2026-01-01"

jobs:
build-linux:
name: Build libquil.so
runs-on: ubuntu-latest
# Pinned rather than ubuntu-latest: the artifact links libsbcl, so it inherits
# the glibc of whatever built it, and a build on 24.04 fails to load on 22.04
# with "version `GLIBC_2.38' not found".
runs-on: ubuntu-22.04

steps:
- name: root suid tar
run: sudo chown root /bin/tar && sudo chmod u+s /bin/tar

- uses: actions/checkout@v2
- uses: actions/checkout@v4
with:
path: "libquil"

- name: Cache SBCL
id: cache-sbcl
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: |
/usr/local/lib/libsbcl.so
/usr/local/lib/sbcl
/usr/local/bin/sbcl
~/quicklisp
~/.sbclrc
key: ${{ runner.os }}-build-${{ hashFiles('**/versions') }}
# env.ImageOS is set by the runner image itself (e.g. "ubuntu22", "macos15");
# unlike runner.os it changes when the image is upgraded,
# so a new image does not reuse a cache built against the old one.
# Note that this variable is stable but not yet documented:
# https://github.com/github/docs/issues/40108
key: ${{ env.ImageOS }}-${{ runner.arch }}-build-${{ hashFiles('**/versions') }}
Comment thread
BatmanAoD marked this conversation as resolved.

- if: steps.cache-sbcl.outputs.cache-hit != 'true'
name: Install SBCL, libraries, and quicklisp
run: |
sudo apt update && sudo apt install -y sbcl build-essential
sudo git clone --single-branch --branch sbcl-2.2.4 https://git.code.sf.net/p/sbcl/sbcl /usr/src/sbcl
cd /usr/src/sbcl && sudo sh make.sh && sudo sh make-shared-library.sh
sudo apt remove -y sbcl
sudo sh install.sh
sudo cp src/runtime/libsbcl.so /usr/local/lib/libsbcl.so

sudo apt install -y wget
wget -P /tmp/ 'https://beta.quicklisp.org/quicklisp.lisp'
sbcl --noinform --non-interactive --load /tmp/quicklisp.lisp --eval "(quicklisp-quickstart:install :dist-url \"http://beta.quicklisp.org/dist/quicklisp/2022-04-01/distinfo.txt\")"
sbcl --noinform --non-interactive --load ~/quicklisp/setup.lisp --eval '(ql-util:without-prompting (ql:add-to-init-file))'
echo "#+quicklisp(push (truename \"$GITHUB_WORKSPACE\") ql:*local-project-directories*)" >> ~/.sbclrc
rm -f /tmp/quicklisp.lisp
cat ~/.sbclrc
sudo apt update && sudo apt install -y build-essential bzip2 wget
# Cross compiling a current SBCL needs a host of roughly the same
# vintage, and 22.04 ships 2.1.11, which fails in make-host-1 with
# "FAILURE-P was set when creating genesis.fasl". Bootstrap from a
# binary release instead. 22.04 is used deliberately, since the artifact
# inherits the glibc of whatever builds it.
wget -q "https://downloads.sourceforge.net/project/sbcl/sbcl/$SBCL_BOOTSTRAP_VERSION/sbcl-$SBCL_BOOTSTRAP_VERSION-x86-64-linux-binary.tar.bz2" -O /tmp/sbcl-bin.tar.bz2
mkdir -p /tmp/sbcl-bin && tar xf /tmp/sbcl-bin.tar.bz2 -C /tmp/sbcl-bin --strip-components=1
cd /tmp/sbcl-bin && sudo sh install.sh
"$GITHUB_WORKSPACE/libquil/scripts/install-sbcl.sh"

- name: Pull Lisp dependencies
run: |
git clone https://github.com/notmgsk/quilc.git $GITHUB_WORKSPACE/quilc && cd $GITHUB_WORKSPACE/quilc && git checkout bffea7fdb972cc9b3a50b790246b6a3143c88c7a
git clone https://github.com/quil-lang/qvm.git $GITHUB_WORKSPACE/qvm && cd $GITHUB_WORKSPACE/qvm && git checkout 4617625cb6053b1adfd3f7aea9cd2be328b225f6
git clone https://github.com/quil-lang/magicl.git $GITHUB_WORKSPACE/magicl
git clone https://github.com/stylewarning/cl-permutation $GITHUB_WORKSPACE/cl-permutation
git clone https://github.com/quil-lang/sbcl-librarian.git $GITHUB_WORKSPACE/sbcl-librarian && cd $GITHUB_WORKSPACE/sbcl-librarian && git checkout 04f7e390c777084ac43b8df9e90593a041da2381
run: "$GITHUB_WORKSPACE/libquil/scripts/clone-lisp-deps.sh"

- name: Install quilc dependencies
run: sudo apt update && sudo apt install -y libblas-dev libffi-dev libffi7 liblapack-dev libz-dev gfortran
# libffi-dev pulls in whichever libffi runtime the image ships; naming a
# version explicitly breaks whenever the runner image moves.
run: sudo apt update && sudo apt install -y libblas-dev libffi-dev liblapack-dev libz-dev gfortran
Comment thread
BatmanAoD marked this conversation as resolved.

- name: Build libquil.so
run: |
cd $GITHUB_WORKSPACE/libquil
ls
sbcl --noinform --non-interactive --eval '(ql:quickload :sbcl-librarian)'
sbcl --dynamic-space-size 8192 --noinform --non-interactive --eval '(ql:quickload :libquil)'
Comment thread
BatmanAoD marked this conversation as resolved.
make

- name: Test
run: |
cd $GITHUB_WORKSPACE/libquil/examples/qvm && LD_LIBRARY_PATH=../.. make test
cd $GITHUB_WORKSPACE/libquil/examples/quilc && LD_LIBRARY_PATH=../.. make test
cd $GITHUB_WORKSPACE/libquil/examples/qvm && LD_LIBRARY_PATH=../..:../../runtime make test
cd $GITHUB_WORKSPACE/libquil/examples/quilc && LD_LIBRARY_PATH=../..:../../runtime make test

- name: Package files
run: |
mkdir -p $GITHUB_WORKSPACE/artifacts/libquil && cp $GITHUB_WORKSPACE/libquil/libquil.h $GITHUB_WORKSPACE/libquil/libquil.so $GITHUB_WORKSPACE/libquil/libquil.core /usr/local/lib/libsbcl.so $GITHUB_WORKSPACE/artifacts/libquil
"$GITHUB_WORKSPACE/libquil/scripts/package-artifact.sh" \
"$GITHUB_WORKSPACE/libquil" "$GITHUB_WORKSPACE/artifacts"

- name: Store artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: linux-amd64
path: ${{ github.workspace }}/artifacts/*
# A directory (not a glob): upload-artifact v4 preserves structure
# relative to it, keeping the libquil/ prefix the release job unzips.
path: ${{ github.workspace }}/artifacts

build-macos:
name: Build libquil.dylib
build-macos-arm:
name: Build Apple-Silicon libquil.dylib
runs-on: macos-latest

steps:

- uses: actions/checkout@v2
- uses: actions/checkout@v4
with:
path: "libquil"

- name: Cache SBCL
id: cache-sbcl-macos
uses: actions/cache@v3
uses: actions/cache@v4
with:
path: |
/usr/local/lib/libsbcl.so
/usr/local/lib/sbcl
/usr/local/bin/sbcl
~/quicklisp
~/.sbclrc
key: ${{ runner.os }}-build-${{ hashFiles('**/macos-versions' )}}
# See the Linux job for why this keys on env.ImageOS.
key: ${{ env.ImageOS }}-${{ runner.arch }}-build-${{ hashFiles('**/versions') }}

- uses: Homebrew/actions/setup-homebrew@master
name: Setup homebrew

- if: steps.cache-sbcl-macos.outputs.cache-hit != 'true'
name: Install SBCL, libraries, and quicklisp
env:
# Homebrew's sbcl is only the cross-compilation host; drop it once the
# build is done so the one we install is the one on PATH.
SBCL_REMOVE_HOST_CMD: "brew remove -f sbcl"
run: |
brew install sbcl git
git clone --branch x86-null-tn https://git.code.sf.net/p/sbcl/sbcl /tmp/sbcl
cd /tmp/sbcl && sudo sh make.sh --without-compact-instance-header --without-immobile-space --without-immobile-code && sudo sh make-shared-library.sh
brew remove -f sbcl
sudo sh install.sh
sudo cp src/runtime/libsbcl.so /usr/local/lib/libsbcl.so

brew install wget
wget -P /tmp/ 'https://beta.quicklisp.org/quicklisp.lisp'
sbcl --noinform --non-interactive --load /tmp/quicklisp.lisp --eval "(quicklisp-quickstart:install :dist-url \"http://beta.quicklisp.org/dist/quicklisp/2022-04-01/distinfo.txt\")"
sbcl --noinform --non-interactive --load ~/quicklisp/setup.lisp --eval '(ql-util:without-prompting (ql:add-to-init-file))'
echo "#+quicklisp(push (truename \"$GITHUB_WORKSPACE\") ql:*local-project-directories*)" >> ~/.sbclrc
rm -f /tmp/quicklisp.lisp
cat ~/.sbclrc
brew install sbcl git wget
"$GITHUB_WORKSPACE/libquil/scripts/install-sbcl.sh"

- name: Pull Lisp dependencies
run: |
git clone https://github.com/notmgsk/quilc.git $GITHUB_WORKSPACE/quilc && cd $GITHUB_WORKSPACE/quilc && git checkout bffea7fdb972cc9b3a50b790246b6a3143c88c7a
git clone https://github.com/quil-lang/qvm.git $GITHUB_WORKSPACE/qvm && cd $GITHUB_WORKSPACE/qvm && git checkout 4617625cb6053b1adfd3f7aea9cd2be328b225f6
git clone https://github.com/quil-lang/magicl.git $GITHUB_WORKSPACE/magicl
git clone https://github.com/stylewarning/cl-permutation $GITHUB_WORKSPACE/cl-permutation
git clone https://github.com/quil-lang/sbcl-librarian.git $GITHUB_WORKSPACE/sbcl-librarian && cd $GITHUB_WORKSPACE/sbcl-librarian && git checkout 04f7e390c777084ac43b8df9e90593a041da2381
run: "$GITHUB_WORKSPACE/libquil/scripts/clone-lisp-deps.sh"

- name: Install quilc dependencies
run: brew install lapack openblas libffi gfortran
run: brew install openblas libffi gfortran

- name: Build libquil.dylib
run: |
cd $GITHUB_WORKSPACE/libquil
ls
sbcl --noinform --non-interactive --eval '(ql:quickload :sbcl-librarian)'
sbcl --dynamic-space-size 8192 --noinform --non-interactive --eval '(ql:quickload :libquil)'
make

- name: ls
Expand All @@ -149,15 +166,18 @@ jobs:

- name: Test
run: |
cd $GITHUB_WORKSPACE/libquil/examples/qvm && DYLD_LIBRARY_PATH=$GITHUB_WORKSPACE/libquil make test
cd $GITHUB_WORKSPACE/libquil/examples/quilc && DYLD_LIBRARY_PATH=$GITHUB_WORKSPACE/libquil make test
cd $GITHUB_WORKSPACE/libquil/examples/qvm && DYLD_LIBRARY_PATH=$GITHUB_WORKSPACE/libquil:$GITHUB_WORKSPACE/libquil/runtime make test
cd $GITHUB_WORKSPACE/libquil/examples/quilc && DYLD_LIBRARY_PATH=$GITHUB_WORKSPACE/libquil:$GITHUB_WORKSPACE/libquil/runtime make test

- name: Package files
run: |
mkdir -p $GITHUB_WORKSPACE/artifacts/libquil && cp $GITHUB_WORKSPACE/libquil/libquil.h $GITHUB_WORKSPACE/libquil/libquil.dylib $GITHUB_WORKSPACE/libquil/libquil.core /usr/local/lib/libsbcl.so $GITHUB_WORKSPACE/artifacts/libquil
"$GITHUB_WORKSPACE/libquil/scripts/package-artifact.sh" \
"$GITHUB_WORKSPACE/libquil" "$GITHUB_WORKSPACE/artifacts"

- name: Store artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: macos
path: ${{ github.workspace }}/artifacts/*
name: macos-arm64
# A directory (not a glob): upload-artifact v4 preserves structure
# relative to it, keeping the libquil/ prefix the release job unzips.
path: ${{ github.workspace }}/artifacts
58 changes: 37 additions & 21 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
name: Release libquil

on:
# Dispatching on main cuts a release; dispatching on any other branch cuts a
# prerelease, so libquil-sys can be built against a libquil that is not yet stable.
workflow_dispatch:
inputs:
type:
description: Bump versions and trigger a new release.
required: true
default: release
options:
- release

jobs:
build:
Expand All @@ -25,40 +20,61 @@ jobs:
git config --global user.name "${{ github.triggering_actor }}"
git config --global user.email "${{ github.triggering_actor }}@users.noreply.github.com"

- uses: actions/checkout@v2
- uses: actions/checkout@v4
with:
fetch-depth: 0
# Release the ref this was dispatched on, not the default branch.
ref: ${{ github.ref }}

# Each artifact is downloaded into its own directory: they contain
# identically named files, so a shared directory would have one overwrite
# the other.
- name: Download linux artifacts
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: linux-amd64
path: artifacts/
path: artifacts/linux-amd64/

- name: Archive linux artifacts
run: |
cd artifacts && zip linux-amd64.zip libquil/libsbcl.so libquil/libquil.so libquil/libquil.core libquil/libquil.h
# -r rather than a file list: the build job already assembled exactly
# the right directory, and naming files here means a new one is left out
# of the archive silently, surfacing only when someone installs it.
cd artifacts/linux-amd64 && zip -r ../linux-amd64.zip libquil

- name: Download macos artifacts
uses: actions/download-artifact@v3
- name: Download macos arm64 artifacts
uses: actions/download-artifact@v4
with:
name: macos
path: artifacts/
name: macos-arm64
path: artifacts/macos-arm64/

- name: Archive linux artifacts
- name: Archive macos arm64 artifacts
run: |
cd artifacts && zip macos.zip libquil/libsbcl.so libquil/libquil.dylib libquil/libquil.core libquil/libquil.h
cd artifacts/macos-arm64 && zip -r ../macos-arm64.zip libquil

- name: List artifacts
run: |
ls -R artifacts/
unzip -l artifacts/linux-amd64.zip
unzip -l artifacts/macos.zip
unzip -l artifacts/macos-arm64.zip

- name: Install Knope
uses: knope-dev/action@v2.0.0
uses: knope-dev/action@v2.1.2
with:
version: 0.11.0
version: 0.23.0 # Test before updating, breaking changes likely: https://github.com/knope-dev/action#install-latest-version

- name: Release
run: knope release -v
env:
# The Release step authenticates with this rather than an argument.
GITHUB_TOKEN: ${{ secrets.PAT }}
run: |
set -euo pipefail

# A release off main is a real one; anywhere else it can only be a
# prerelease, which is how libquil gets published for testing while an ABI
# change is still under review.
if [[ "$GITHUB_REF" == "refs/heads/main" ]]; then
knope release -v
else
knope release -v --prerelease-label=rc
fi
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,7 @@ libquil.c
libquil.core
libquil.h
libquil.so
libquil.dylib
libquil.py
build/
runtime/
28 changes: 28 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,31 @@
## 0.4.0-rc.1 (2026-08-26)

### Breaking Changes

- build against modern sbcl-librarian

### Features

- install to any prefix, and need root only when the prefix demands it
- add `make install`, and document installing without root

### Fixes

- load OpenBLAS into the image before magicl picks a backend
- check for BLAS and LAPACK, and install without sudo when already root
- say what the SUDO_USER guard in install.sh actually checks

## 0.4.0-rc.0 (2026-08-13)

### Breaking Changes

- build against modern sbcl-librarian

### Fixes

- load OpenBLAS into the image before magicl picks a backend
- check for BLAS and LAPACK, and install without sudo when already root

## 0.3.2 (2023-12-14)

### Fixes
Expand Down
Loading
Loading