From 4cbf5c8c9d736dd2e3ad0c1347d2529b51316cb5 Mon Sep 17 00:00:00 2001 From: Kyle J Strand Date: Tue, 11 Aug 2026 13:52:04 -0600 Subject: [PATCH 1/9] feat!: build against libquil on modern sbcl-librarian libquil no longer ships a core the caller initializes explicitly; the libsbcl_librarian runtime brings Lisp up from a constructor when it loads, and libquil is the generated bindings on top. The core-file search and the init(core) call are gone, along with LIBQUIL_CORE_PATH and the CoreFileNotFound error; init_libquil now only makes libquil's symbols globally visible, which the Python extension still needs. Errors move to the runtime's API: lisp_err_t and get_error_message replace libquil_error_t and libquil_error. The generated header declares real functions rather than function pointers, so bindgen no longer wraps them in Option and the .unwrap() calls on binding functions are dropped. build.rs links libsbcl_librarian alongside libquil, feeds bindgen the runtime's header and include directory (libquil.h now includes sbcl_librarian_err.h), and accepts LIBQUIL_LIB_PATH for installs that keep headers and libraries in separate directories. It also reports its own errors, since Cargo prints a build script's error with Debug, and says plainly when it finds a libquil too old to carry the runtime headers. CI installs $LIBQUIL_VERSION, which has to be a libquil release from after this change, and the macOS job moves off the Intel runner: libquil no longer publishes Intel macOS binaries. The macOS __PAGEZERO link argument is dropped: the Lisp image is mapped by the runtime library now, not by the consumer executable. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/test.yml | 13 +++++-- lib/build.rs | 70 ++++++++++++++++++++++++++++++++++---- lib/src/lib.rs | 48 +++++++------------------- lib/src/quilc.rs | 36 ++++++++++---------- lib/src/qvm.rs | 28 +++++++-------- 5 files changed, 117 insertions(+), 78 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 59bf84c..5c64789 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -6,6 +6,13 @@ on: branches: - 'main' +env: + # The libquil release these bindings are built against. libquil's move to modern + # sbcl-librarian changed its C ABI and the set of files it installs, so this crate + # needs a release from after that change: 0.3.x installs neither the runtime + # headers nor libsbcl_librarian, and the build fails in build.rs. + LIBQUIL_VERSION: "0.3.0" + jobs: test-linux: runs-on: ubuntu-22.04 @@ -20,14 +27,14 @@ jobs: - uses: dtolnay/rust-toolchain@stable - name: Install libquil run: | - curl https://raw.githubusercontent.com/rigetti/libquil/main/install.sh | bash -s 0.3.0 + curl https://raw.githubusercontent.com/rigetti/libquil/main/install.sh | bash -s $LIBQUIL_VERSION - name: Run tests run: | cd $GITHUB_WORKSPACE/lib cargo test test-macos: - runs-on: macos-15-intel + runs-on: macos-latest steps: - uses: actions/checkout@v5 with: @@ -37,7 +44,7 @@ jobs: run: brew install lapack openblas - uses: dtolnay/rust-toolchain@stable - name: Install libquil - run: 'curl https://raw.githubusercontent.com/rigetti/libquil/main/install.sh | bash -s 0.3.0' + run: 'curl https://raw.githubusercontent.com/rigetti/libquil/main/install.sh | bash -s $LIBQUIL_VERSION' - name: Run tests run: | cd $GITHUB_WORKSPACE/lib diff --git a/lib/build.rs b/lib/build.rs index af6bfcc..82c2dbd 100644 --- a/lib/build.rs +++ b/lib/build.rs @@ -3,8 +3,15 @@ use std::path::PathBuf; #[derive(Debug, thiserror::Error)] enum Error { - #[error("Could not find error in any of the standard locations. Try setting C_INCLUDE_PATH or LIBQUIL_SRC_PATH")] + #[error("Could not find libquil.h in any of the standard locations. Try setting C_INCLUDE_PATH or LIBQUIL_SRC_PATH")] HeaderNotFound, + #[error( + "Found libquil.h at {0}, but no sbcl_librarian.h beside it. This crate requires a libquil \ + built against modern sbcl-librarian, which installs the runtime headers alongside \ + libquil.h; an older libquil (0.3.x or earlier) does not have them. Install a newer \ + libquil, or set LIBQUIL_SRC_PATH to a build that has one." + )] + RuntimeHeaderNotFound(String), #[error("Could not read environment variable: {0}")] InvalidEnvvar(#[from] env::VarError), } @@ -35,15 +42,48 @@ fn get_header_path() -> Result { fn get_lib_search_paths() -> Vec { let mut paths = vec!["/usr/local/lib".to_string(), "/usr/lib".to_string()]; + // For installs that do not use /usr/local, where the headers and libraries live + // in separate directories and LIBQUIL_SRC_PATH names only the former. + let libquil_lib_path: Option<&'static str> = option_env!("LIBQUIL_LIB_PATH"); + if let Some(libquil_lib_path) = libquil_lib_path { + paths.insert(0, libquil_lib_path.to_string()); + } + let libquil_src_path: Option<&'static str> = option_env!("LIBQUIL_SRC_PATH"); if let Some(libquil_src_path) = libquil_src_path { + // libquil is a FASL library loaded into the libsbcl_librarian runtime, so + // both must be found. A source tree keeps the runtime in a subdirectory; + // an installed layout puts everything in one directory. + paths.insert(0, format!("{libquil_src_path}/runtime")); paths.insert(0, libquil_src_path.to_string()); } paths } -fn main() -> Result<(), Error> { +/// Directories to search for headers. `libquil.h` includes `sbcl_librarian_err.h`, +/// and `get_error_message` is declared in `sbcl_librarian.h`, both of which ship +/// with the runtime. +fn get_include_paths(libquil_header_path: &std::path::Path) -> Vec { + let mut paths = Vec::new(); + if let Some(dir) = libquil_header_path.parent() { + paths.push(dir.to_path_buf()); + paths.push(dir.join("runtime")); + } + paths.retain(|p| p.exists()); + paths +} + +fn main() { + // Cargo prints a build script's error with Debug, which would hide the + // explanation these errors carry, so report it and exit rather than returning it. + if let Err(error) = build() { + eprintln!("\nerror: {error}\n"); + std::process::exit(1); + } +} + +fn build() -> Result<(), Error> { let libquil_header_path = get_header_path()?; for path in get_lib_search_paths() { @@ -51,6 +91,9 @@ fn main() -> Result<(), Error> { } println!("cargo:rustc-link-lib=quil"); + // The runtime that hosts libquil: it supplies the Lisp image, the error API + // (get_error_message) and the handle API (lisp_release_handle). + println!("cargo:rustc-link-lib=sbcl_librarian"); // Tell cargo to rerun if the libquil implementation has changed println!( @@ -58,11 +101,7 @@ fn main() -> Result<(), Error> { libquil_header_path.clone().display() ); - // If this isn't set on MacOS, memory allocation errors occur when trying to initialize the - // library - if cfg!(target_os = "macos") { - println!("cargo:rustc-link-arg=-pagezero_size 0x100000"); - } + let include_paths = get_include_paths(&libquil_header_path); // The bindgen::Builder is the main entry point // to bindgen, and lets you build up options for @@ -71,6 +110,23 @@ fn main() -> Result<(), Error> { // The input header we would like to generate // bindings for. .header(libquil_header_path.to_string_lossy()) + // ...and the runtime's header, which declares the error API that libquil's + // functions report through. + .header( + include_paths + .iter() + .map(|dir| dir.join("sbcl_librarian.h")) + .find(|path| path.exists()) + .ok_or_else(|| { + Error::RuntimeHeaderNotFound(libquil_header_path.display().to_string()) + })? + .to_string_lossy(), + ) + .clang_args( + include_paths + .iter() + .map(|dir| format!("-I{}", dir.display())), + ) // Tell cargo to invalidate the built crate whenever any of the // included header files changed. .parse_callbacks(Box::new(bindgen::CargoCallbacks)) diff --git a/lib/src/lib.rs b/lib/src/lib.rs index d353088..7cfe1a2 100644 --- a/lib/src/lib.rs +++ b/lib/src/lib.rs @@ -2,14 +2,9 @@ #![allow(non_camel_case_types)] #![allow(non_snake_case)] -use std::{ - ffi::{CStr, CString}, - path::PathBuf, - str::Utf8Error, - sync::Once, -}; +use std::{ffi::CStr, str::Utf8Error, sync::Once}; -use bindings::{libquil_error, libquil_error_t, libquil_error_t_LIBQUIL_ERROR_SUCCESS}; +use bindings::{get_error_message, lisp_err_t, lisp_err_t_LISP_ERR_SUCCESS}; pub mod quilc; pub mod qvm; @@ -23,32 +18,17 @@ static START: Once = Once::new(); #[derive(Debug, thiserror::Error)] pub enum Error { - #[error("Could not find libquil core file. Set the LIBQUIL_CORE_PATH environment variable.")] - CoreFileNotFound, #[error("Unsupported Operating System: {0}")] UnsupportedOperatingSystem(String), } -fn find_core_file() -> Result { - let mut paths = vec!["/usr/local/lib/libquil.core", "/usr/lib/libquil.core"]; - - let libquil_src_path: Option<&'static str> = option_env!("LIBQUIL_CORE_PATH"); - if let Some(libquil_src_path) = libquil_src_path { - paths.insert(0, libquil_src_path); - } - - for path in paths { - if PathBuf::from(path).exists() { - return Ok(path.to_string()); - } - } - - Err(Error::CoreFileNotFound) -} - -/// Initializes libquil using it's core image. No-op after the first call. +/// Prepares libquil for use. No-op after the first call. +/// +/// There is no core file to locate and no initialization call to make: the Lisp +/// image is brought up by a constructor in the libsbcl_librarian runtime when it is +/// loaded, and libquil's own constructor then loads its embedded FASL bundles into +/// that image. All this function does is make libquil's symbols globally visible. pub(crate) fn init_libquil() -> Result<(), Error> { - let core_path = find_core_file()?; let library_name = match std::env::consts::OS { "linux" => Ok("libquil.so".to_string()), "macos" => Ok("libquil.dylib".to_string()), @@ -56,8 +36,6 @@ pub(crate) fn init_libquil() -> Result<(), Error> { }?; START.call_once(|| { - let ptr = CString::new(core_path).unwrap().into_raw(); - unsafe { // The library built by maturin does link to libquil, but // the linker does not make the libquil symbols available @@ -69,24 +47,22 @@ pub(crate) fn init_libquil() -> Result<(), Error> { libloading::os::unix::RTLD_NOW | libloading::os::unix::RTLD_GLOBAL, ) .unwrap(); - bindings::init(ptr); - let _ = CString::from_raw(ptr); } }); Ok(()) } -pub(crate) fn handle_libquil_error(errno: libquil_error_t) -> Result<(), String> { - if errno == libquil_error_t_LIBQUIL_ERROR_SUCCESS { +pub(crate) fn handle_libquil_error(errno: lisp_err_t) -> Result<(), String> { + if errno == lisp_err_t_LISP_ERR_SUCCESS { return Ok(()); } let mut error_str_ptr: *mut std::os::raw::c_char = std::ptr::null_mut(); unsafe { - let err = libquil_error.unwrap()(&mut error_str_ptr); - if err != 0 { + let err = get_error_message(&mut error_str_ptr); + if err != lisp_err_t_LISP_ERR_SUCCESS { return Err("unknown error occurred".to_string()); } let error_str = CStr::from_ptr(error_str_ptr).to_str().unwrap(); diff --git a/lib/src/quilc.rs b/lib/src/quilc.rs index 578cd4c..2b1d877 100644 --- a/lib/src/quilc.rs +++ b/lib/src/quilc.rs @@ -66,7 +66,7 @@ impl TryFrom for Chip { let mut chip: chip_specification = std::ptr::null_mut(); unsafe { - let err = quilc_parse_chip_spec_isa_json.unwrap()(ptr, &mut chip); + let err = quilc_parse_chip_spec_isa_json(ptr, &mut chip); crate::handle_libquil_error(err).map_err(Error::ParseChip)?; let _ = CString::from_raw(ptr); } @@ -86,7 +86,7 @@ impl FromStr for Chip { impl Drop for Chip { fn drop(&mut self) { unsafe { - bindings::lisp_release_handle.unwrap()(self.0 as *mut _); + bindings::lisp_release_handle(self.0 as *mut _); } } } @@ -109,7 +109,7 @@ impl TryFrom for Program { let mut parsed_program: quil_program = std::ptr::null_mut(); unsafe { - let err = quilc_parse_quil.unwrap()(ptr, &mut parsed_program); + let err = quilc_parse_quil(ptr, &mut parsed_program); crate::handle_libquil_error(err).map_err(Error::ParseQuil)?; let _ = CString::from_raw(ptr); } @@ -128,7 +128,7 @@ impl FromStr for Program { impl Drop for Program { fn drop(&mut self) { - unsafe { bindings::lisp_release_handle.unwrap()(self.0 as *mut _) } + unsafe { bindings::lisp_release_handle(self.0 as *mut _) }; } } @@ -138,7 +138,7 @@ impl Program { unsafe { let mut program_string_ptr: *mut std::os::raw::c_char = std::ptr::null_mut(); - let err = quilc_program_string.unwrap()( + let err = quilc_program_string( self.0, std::ptr::addr_of_mut!(program_string_ptr) as *mut _, ); @@ -177,7 +177,7 @@ pub fn program_memory_type(program: &Program, region: &str) -> Result Result].unwrap()( + let err = []( $metadata_ptr, std::ptr::addr_of_mut!(var) as *mut _, std::ptr::addr_of_mut!(present), @@ -250,7 +250,7 @@ impl TryFrom for CompilationMetadata { let mut rewiring_ptr: *mut std::ffi::c_uint = std::ptr::null_mut(); let mut rewiring_len = 0; - let err = quilc_compilation_metadata_get_final_rewiring.unwrap()( + let err = quilc_compilation_metadata_get_final_rewiring( value, std::ptr::addr_of_mut!(rewiring_ptr) as *mut _, std::ptr::addr_of_mut!(rewiring_len) as *mut _, @@ -288,7 +288,7 @@ pub fn compile_protoquil(program: &Program, chip: &Chip) -> Result Result Result { let mut chip: chip_specification = std::ptr::null_mut(); unsafe { - let err = quilc_build_nq_linear_chip.unwrap()(2, &mut chip); + let err = quilc_build_nq_linear_chip(2, &mut chip); crate::handle_libquil_error(err).map_err(Error::BuildNqLinearChip)?; } @@ -327,7 +327,7 @@ pub fn print_program(program: &Program) -> Result<(), Error> { init_libquil()?; unsafe { - let err = quilc_print_program.unwrap()(program.0); + let err = quilc_print_program(program.0); crate::handle_libquil_error(err).map_err(Error::PrintProgram)?; } @@ -355,7 +355,7 @@ pub fn conjugate_pauli_by_clifford( .into_iter() .map(CString::into_raw) .collect::>(); - let err = quilc_conjugate_pauli_by_clifford.unwrap()( + let err = quilc_conjugate_pauli_by_clifford( pauli_indices.as_mut_ptr() as *mut _, pauli_indices.len() as i32, pauli_terms.as_mut_ptr() as *mut _, @@ -409,7 +409,7 @@ pub fn generate_rb_sequence( }; unsafe { - let err = quilc_generate_rb_sequence.unwrap()( + let err = quilc_generate_rb_sequence( depth, qubits, gateset.as_mut_ptr() as *mut _, @@ -449,18 +449,18 @@ pub fn get_version_info() -> Result { unsafe { let mut version_info: quilc_version_info = std::ptr::null_mut(); - let err = quilc_get_version_info.unwrap()(&mut version_info); + let err = quilc_get_version_info(&mut version_info); crate::handle_libquil_error(err).map_err(Error::PrintProgram)?; let mut version_ptr: *mut std::os::raw::c_char = std::ptr::null_mut(); - let err = quilc_version_info_version.unwrap()( + let err = quilc_version_info_version( version_info, std::ptr::addr_of_mut!(version_ptr) as *mut _, ); crate::handle_libquil_error(err).map_err(Error::PrintProgram)?; let mut githash_ptr: *mut std::os::raw::c_char = std::ptr::null_mut(); - let err = quilc_version_info_githash.unwrap()( + let err = quilc_version_info_githash( version_info, std::ptr::addr_of_mut!(githash_ptr) as *mut _, ); diff --git a/lib/src/qvm.rs b/lib/src/qvm.rs index 3fb87db..a27b8b4 100644 --- a/lib/src/qvm.rs +++ b/lib/src/qvm.rs @@ -50,18 +50,18 @@ pub fn get_version_info() -> Result { unsafe { let mut version_info: qvm_version_info = std::ptr::null_mut(); - let err = qvm_get_version_info.unwrap()(&mut version_info); + let err = qvm_get_version_info(&mut version_info); crate::handle_libquil_error(err).map_err(Error::VersionInfo)?; let mut version_ptr: *mut std::os::raw::c_char = std::ptr::null_mut(); - let err = qvm_version_info_version.unwrap()( + let err = qvm_version_info_version( version_info, std::ptr::addr_of_mut!(version_ptr) as *mut _, ); crate::handle_libquil_error(err).map_err(Error::VersionInfo)?; let mut githash_ptr: *mut std::os::raw::c_char = std::ptr::null_mut(); - let err = qvm_version_info_githash.unwrap()( + let err = qvm_version_info_githash( version_info, std::ptr::addr_of_mut!(githash_ptr) as *mut _, ); @@ -86,7 +86,7 @@ impl TryFrom> for QvmMultishotAddresses let mut addresses_ptr: qvm_multishot_addresses = std::ptr::null_mut(); unsafe { - let err = qvm_multishot_addresses_new.unwrap()(&mut addresses_ptr); + let err = qvm_multishot_addresses_new(&mut addresses_ptr); handle_libquil_error(err).map_err(Error::MultishotAddresses)?; } @@ -95,14 +95,14 @@ impl TryFrom> for QvmMultishotAddresses let name_ptr = CString::new(name.clone())?.into_raw(); match address { MultishotAddressRequest::All => { - let err = bindings::qvm_multishot_addresses_set_all.unwrap()( + let err = bindings::qvm_multishot_addresses_set_all( addresses_ptr, name_ptr, ); handle_libquil_error(err).map_err(Error::MultishotAddresses)?; } MultishotAddressRequest::Indices(indices) => { - let err = bindings::qvm_multishot_addresses_set.unwrap()( + let err = bindings::qvm_multishot_addresses_set( addresses_ptr, name_ptr, indices.to_vec().as_mut_ptr() as *mut _, @@ -150,7 +150,7 @@ macro_rules! multishot_get_all { let mut results = std::ptr::null_mut(); let mut results_len = 0; unsafe { - let err = bindings::qvm_multishot_result_get_all.unwrap()( + let err = bindings::qvm_multishot_result_get_all( $result, $name, $trial, @@ -167,7 +167,7 @@ macro_rules! multishot_get { ($result:ident, $name:ident, $trial:ident, $indices:ident, $ty:tt) => {{ let mut results: Vec<$ty> = vec![$ty::default(); $indices.len()]; unsafe { - let err = bindings::qvm_multishot_result_get.unwrap()( + let err = bindings::qvm_multishot_result_get( $result, $name, $trial, @@ -280,7 +280,7 @@ pub fn multishot( }; unsafe { - let err = bindings::qvm_multishot.unwrap()( + let err = bindings::qvm_multishot( program.0, addresses.ptr, trials, @@ -383,7 +383,7 @@ pub fn multishot( } unsafe { - bindings::lisp_release_handle.unwrap()(result_ptr as *mut _); + bindings::lisp_release_handle(result_ptr as *mut _); } Ok(multishot) @@ -429,7 +429,7 @@ pub fn multishot_measure( }; unsafe { - let err = bindings::qvm_multishot_measure.unwrap()( + let err = bindings::qvm_multishot_measure( program.0, qubits.as_mut_ptr() as *mut _, qubits.len() as i32, @@ -464,7 +464,7 @@ pub fn wavefunction( }; unsafe { - let err = bindings::qvm_wavefunction.unwrap()( + let err = bindings::qvm_wavefunction( program.0, rng_seed_ptr as *mut _, std::ptr::addr_of_mut!(results) as *mut _, @@ -499,7 +499,7 @@ pub fn probabilities( }; unsafe { - let err = bindings::qvm_probabilities.unwrap()( + let err = bindings::qvm_probabilities( program.0, rng_seed_ptr as *mut _, probabilities.as_mut_ptr() as *mut _, @@ -526,7 +526,7 @@ pub fn expectation( unsafe { let mut expectations = vec![0.0; operators.len()]; - let err = bindings::qvm_expectation.unwrap()( + let err = bindings::qvm_expectation( program.0, operators .iter() From 45a55926b9028db4cd33db5afb8c26ee81503613 Mon Sep 17 00:00:00 2001 From: Kyle J Strand Date: Tue, 11 Aug 2026 13:52:04 -0600 Subject: [PATCH 2/9] chore: update python package authors Author/email change that was present in the working copy; separated out so it is not mixed into unrelated CI work. --- python/pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/pyproject.toml b/python/pyproject.toml index af8b9ad..c88a26d 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -3,7 +3,7 @@ name = "libquil" requires-python = ">=3.8" description = "Python bindings for quilc" license = { text = "Apache-2.0" } -authors = [{ name = "Rigetti Computing", email = "softapps@rigetti.com" }] +authors = [{ name = "Rigetti QPU Software", email = "qpu-software@rigetti.com" }] classifiers = [ "Development Status :: 3 - Alpha", "License :: OSI Approved :: Apache Software License", From a3d2917bbb83221c69975e167bec885c281cdbed Mon Sep 17 00:00:00 2001 From: Kyle J Strand Date: Tue, 11 Aug 2026 13:52:04 -0600 Subject: [PATCH 3/9] ci: add a prerelease workflow and test against the libquil prerelease libquil-sys is only usable with a matching libquil, so an ABI change has to be published somewhere testable before either side can be released for real. There was no way to do that: knope.toml defined only a 'release' workflow, and the dispatch input listing it was not a choice input, so its options list was inert. Add a 'prerelease' knope workflow that cuts an -rc version and marks the GitHub release as a prerelease, which still triggers the existing crates.io publish. Cargo never resolves a prerelease unless asked for by name, so it is safe to publish alongside stable versions. Verified with knope 0.10.0 and 0.11.0: the config validates and the workflow dry-runs to 0.5.0-rc.0. The test workflow now takes the libquil release to install, and the repository and ref to fetch install.sh from -- they have to move together, because the installer that ships with a release knows which files that release contains, and the move to modern sbcl-librarian added the runtime directory. They currently point at v0.4.0-rc.0 in a fork, since the libquil change is not merged; revert to rigetti/libquil and a stable version once it lands. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/prepare-release.yml | 8 +++++++ .github/workflows/test.yml | 15 +++++++++++--- knope.toml | 30 +++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 3 deletions(-) diff --git a/.github/workflows/prepare-release.yml b/.github/workflows/prepare-release.yml index 9ed9ed7..2bf9b33 100644 --- a/.github/workflows/prepare-release.yml +++ b/.github/workflows/prepare-release.yml @@ -6,9 +6,17 @@ on: type: description: Bump versions and trigger a new release. required: true + # `options` only takes effect on a choice input; without this the list was + # inert and the field was a free-text string. + type: choice default: release options: - release + # Cuts an -rc version and marks the GitHub release as a prerelease, which + # still publishes to crates.io. Use it to make a build testable before + # committing to a stable version -- notably when libquil's ABI has changed + # and both sides need releasing together. + - prerelease jobs: prepare-release: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5c64789..0b7d4f1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,7 +11,16 @@ env: # sbcl-librarian changed its C ABI and the set of files it installs, so this crate # needs a release from after that change: 0.3.x installs neither the runtime # headers nor libsbcl_librarian, and the build fails in build.rs. - LIBQUIL_VERSION: "0.3.0" + LIBQUIL_VERSION: "0.4.0-rc.1" + # install.sh is fetched from this ref of libquil. It has to match the release + # above: the installer that ships with a release knows which files that release + # contains, and the modern-sbcl-librarian layout added the runtime directory. + LIBQUIL_INSTALL_REF: "sbcl-librarian-runtime" + # Temporary, until the libquil change is merged and released from rigetti/libquil: + # the prerelease with the new ABI is published from a fork, and install.sh has to + # be fetched from the same place so it knows which files that release contains. + LIBQUIL_INSTALL_REPO: "BatmanAoD/libquil" + LIBQUIL_RELEASE_REPO: "BatmanAoD/libquil" jobs: test-linux: @@ -27,7 +36,7 @@ jobs: - uses: dtolnay/rust-toolchain@stable - name: Install libquil run: | - curl https://raw.githubusercontent.com/rigetti/libquil/main/install.sh | bash -s $LIBQUIL_VERSION + curl https://raw.githubusercontent.com/$LIBQUIL_INSTALL_REPO/$LIBQUIL_INSTALL_REF/install.sh | bash -s $LIBQUIL_VERSION - name: Run tests run: | cd $GITHUB_WORKSPACE/lib @@ -44,7 +53,7 @@ jobs: run: brew install lapack openblas - uses: dtolnay/rust-toolchain@stable - name: Install libquil - run: 'curl https://raw.githubusercontent.com/rigetti/libquil/main/install.sh | bash -s $LIBQUIL_VERSION' + run: 'curl https://raw.githubusercontent.com/$LIBQUIL_INSTALL_REPO/$LIBQUIL_INSTALL_REF/install.sh | bash -s $LIBQUIL_VERSION' - name: Run tests run: | cd $GITHUB_WORKSPACE/lib diff --git a/knope.toml b/knope.toml index c35c72e..f963b25 100644 --- a/knope.toml +++ b/knope.toml @@ -23,6 +23,36 @@ command = "git push" [[workflows.steps]] type = "Release" +# Same as "release", but produces a prerelease version (e.g. 0.5.0-rc.1) and marks +# the GitHub release as a prerelease. Publishing that to crates.io is safe: Cargo +# never resolves a prerelease unless a dependant asks for it by name, so it is the +# way to make a build available for testing before committing to a stable version. +# +# This exists because libquil-sys is only usable with a matching libquil, so a +# breaking change to libquil's ABI has to be published somewhere testable before +# either side can be released for real. +[[workflows]] +name = "prerelease" + +[[workflows.steps]] +type = "PrepareRelease" +prerelease_label = "rc" + +[[workflows.steps]] +type = "Command" +command = "cargo update -w" + +[[workflows.steps]] +type = "Command" +command = "git add Cargo.lock && git commit -m \"chore: prepare new prerelease(s) [skip ci]\"" + +[[workflows.steps]] +type = "Command" +command = "git push" + +[[workflows.steps]] +type = "Release" + [github] owner = "rigetti" repo = "libquil-sys" From 736a08e2ea767f83258fec6ac5c6aff0a9fe0c7a Mon Sep 17 00:00:00 2001 From: BatmanAoD Date: Wed, 12 Aug 2026 04:29:02 +0000 Subject: [PATCH 4/9] chore: prepare new prerelease(s) [skip ci] --- Cargo.lock | 2 +- lib/CHANGELOG.md | 6 ++++++ lib/Cargo.toml | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7d7429c..1e803a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -434,7 +434,7 @@ checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] name = "libquil-sys" -version = "0.4.2" +version = "0.5.0-rc.0" dependencies = [ "assert2", "bindgen", diff --git a/lib/CHANGELOG.md b/lib/CHANGELOG.md index c9f3801..628c01a 100644 --- a/lib/CHANGELOG.md +++ b/lib/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.5.0-rc.0 (2026-08-12) + +### Breaking Changes + +#### build against libquil on modern sbcl-librarian + ## 0.4.2 (2026-05-21) ### Fixes diff --git a/lib/Cargo.toml b/lib/Cargo.toml index c504938..06a74f8 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "libquil-sys" description = "High-level bindings to libquil" -version = "0.4.2" +version = "0.5.0-rc.0" edition = "2021" license = "Apache-2.0" repository = "https://github.com/rigetti/libquil-sys" From 545d05df81eba544dd2670d0383b893a6e3d40dc Mon Sep 17 00:00:00 2001 From: Kyle J Strand Date: Tue, 11 Aug 2026 22:36:49 -0600 Subject: [PATCH 5/9] ci: fix the release/prerelease pipeline Cutting a prerelease from a branch produced a tag pointing at the wrong code. knope 0.10/0.11 create the GitHub release against the default branch, so the version bump landed on the branch while the tag landed on main -- and the publish job, which checks out whatever that tag resolves to, then tried to republish main's already-released version: error: crate libquil-sys@0.4.2 already exists on crates.io index Adopt the setup rigetti-pyo3 arrived at (36a1850, 9b5235c, 3505971): - knope 0.23, which tags the ref being released and takes --prerelease-label, so the separate prerelease workflow in knope.toml is no longer needed; - the ref decides what gets cut: main releases, anything else prereleases; - check out ${{ github.ref }} so a release acts on the dispatched branch; - pass the token to the Release step through GITHUB_TOKEN, which is how it authenticates; - dry-run the release on pull requests, so a broken config is visible before it is dispatched. The publish job now checks out the release tag explicitly, so it always publishes exactly what was tagged rather than whatever the target commitish points at. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/prepare-release.yml | 51 ++++++++++++++++----------- .github/workflows/release-library.yml | 15 +++++++- knope.toml | 31 +--------------- 3 files changed, 46 insertions(+), 51 deletions(-) diff --git a/.github/workflows/prepare-release.yml b/.github/workflows/prepare-release.yml index 2bf9b33..eea4bdc 100644 --- a/.github/workflows/prepare-release.yml +++ b/.github/workflows/prepare-release.yml @@ -1,41 +1,52 @@ name: Prepare Release on: + pull_request: + branches: + - main workflow_dispatch: - inputs: - type: - description: Bump versions and trigger a new release. - required: true - # `options` only takes effect on a choice input; without this the list was - # inert and the field was a free-text string. - type: choice - default: release - options: - - release - # Cuts an -rc version and marks the GitHub release as a prerelease, which - # still publishes to crates.io. Use it to make a build testable before - # committing to a stable version -- notably when libquil's ABI has changed - # and both sides need releasing together. - - prerelease jobs: prepare-release: runs-on: ubuntu-22.04 - env: - GITHUB_TOKEN: ${{ secrets.PAT }} steps: - uses: actions/checkout@v5 with: fetch-depth: 0 + # Release from the ref this was dispatched on, so a prerelease cut from a + # branch tags that branch rather than the default one. + ref: ${{ github.ref }} token: ${{ secrets.PAT }} - name: Install Knope - uses: knope-dev/action@v2.1.0 + uses: knope-dev/action@v2.1.2 with: - version: 0.10.0 # Test before updating, breaking changes likely: https://github.com/knope-dev/action#install-latest-version + # 0.23 is needed for `--prerelease-label` and for tagging the ref being + # released. 0.10 tagged the default branch instead, so a prerelease cut from + # a branch produced a tag pointing at main's version, and the publish job + # then tried to republish that already-released version. + version: 0.23.0 # Test before updating, breaking changes likely: https://github.com/knope-dev/action#install-latest-version - run: | git config --global user.name "${{ github.triggering_actor }}" git config --global user.email "${{ github.triggering_actor}}@users.noreply.github.com" + + # On a pull request, only show what a release would do. + - name: Dry-run Release + if: github.event_name == 'pull_request' + run: knope release --verbose --dry-run + - name: Prepare Release - run: knope ${{ inputs.type }} --verbose if: github.event_name == 'workflow_dispatch' + 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 a change that needs a matching libquil release + # gets published for testing before either side is final. + if [[ "$GITHUB_REF" == "refs/heads/main" ]]; then + knope release --verbose + else + knope release --verbose --prerelease-label=rc + fi diff --git a/.github/workflows/release-library.yml b/.github/workflows/release-library.yml index 9034f48..45b9f12 100644 --- a/.github/workflows/release-library.yml +++ b/.github/workflows/release-library.yml @@ -13,7 +13,20 @@ jobs: - uses: actions/checkout@v5 with: fetch-depth: 0 + # Publish exactly what was tagged. Without this the checkout follows the + # release's target commitish, which is not necessarily the commit carrying + # the version bump -- a prerelease cut from a branch tagged main, and this + # job then tried to republish main's already-released version. + ref: ${{ github.event.release.tag_name || github.ref }} token: ${{ secrets.PAT }} - uses: dtolnay/rust-toolchain@stable - - run: cargo publish --no-verify --manifest-path=lib/Cargo.toml --token ${{ secrets.CRATES_IO_TOKEN }} + - name: Publish to crates.io + run: | + set -euo pipefail + version="$(cargo pkgid --manifest-path=lib/Cargo.toml | sed -E 's|.*[#@]||')" + echo "Publishing libquil-sys $version" + + # --no-verify: the crate cannot be built without libquil installed, which + # is not available on this runner. + cargo publish --no-verify --manifest-path=lib/Cargo.toml --token ${{ secrets.CRATES_IO_TOKEN }} diff --git a/knope.toml b/knope.toml index f963b25..8484a3a 100644 --- a/knope.toml +++ b/knope.toml @@ -14,6 +14,7 @@ command = "cargo update -w" [[workflows.steps]] type = "Command" +shell = true command = "git add Cargo.lock && git commit -m \"chore: prepare new release(s) [skip ci]\"" [[workflows.steps]] @@ -23,36 +24,6 @@ command = "git push" [[workflows.steps]] type = "Release" -# Same as "release", but produces a prerelease version (e.g. 0.5.0-rc.1) and marks -# the GitHub release as a prerelease. Publishing that to crates.io is safe: Cargo -# never resolves a prerelease unless a dependant asks for it by name, so it is the -# way to make a build available for testing before committing to a stable version. -# -# This exists because libquil-sys is only usable with a matching libquil, so a -# breaking change to libquil's ABI has to be published somewhere testable before -# either side can be released for real. -[[workflows]] -name = "prerelease" - -[[workflows.steps]] -type = "PrepareRelease" -prerelease_label = "rc" - -[[workflows.steps]] -type = "Command" -command = "cargo update -w" - -[[workflows.steps]] -type = "Command" -command = "git add Cargo.lock && git commit -m \"chore: prepare new prerelease(s) [skip ci]\"" - -[[workflows.steps]] -type = "Command" -command = "git push" - -[[workflows.steps]] -type = "Release" - [github] owner = "rigetti" repo = "libquil-sys" From 7b4bd4d3bf26417753bc1e08419f43ed35a5b7a2 Mon Sep 17 00:00:00 2001 From: BatmanAoD Date: Wed, 12 Aug 2026 05:12:55 +0000 Subject: [PATCH 6/9] chore: prepare new release(s) [skip ci] --- Cargo.lock | 2 +- lib/CHANGELOG.md | 6 ++++++ lib/Cargo.toml | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1e803a6..4cb8738 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -434,7 +434,7 @@ checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] name = "libquil-sys" -version = "0.5.0-rc.0" +version = "0.5.0-rc.1" dependencies = [ "assert2", "bindgen", diff --git a/lib/CHANGELOG.md b/lib/CHANGELOG.md index 628c01a..b6742a4 100644 --- a/lib/CHANGELOG.md +++ b/lib/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.5.0-rc.1 (2026-08-12) + +### Breaking Changes + +- build against libquil on modern sbcl-librarian + ## 0.5.0-rc.0 (2026-08-12) ### Breaking Changes diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 06a74f8..e7bdc1a 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "libquil-sys" description = "High-level bindings to libquil" -version = "0.5.0-rc.0" +version = "0.5.0-rc.1" edition = "2021" license = "Apache-2.0" repository = "https://github.com/rigetti/libquil-sys" From 7e913f3f1e4f4bc30b4353009e2cf32320215889 Mon Sep 17 00:00:00 2001 From: Kyle J Strand Date: Wed, 12 Aug 2026 09:50:19 -0600 Subject: [PATCH 7/9] fix: read libquil path envvars at build-script runtime get_header_path and get_lib_search_paths read LIBQUIL_SRC_PATH, LIBQUIL_LIB_PATH and C_INCLUDE_PATH with option_env!, which resolves when the build script is *compiled*. The chosen paths were baked into the compiled build script, and nothing told cargo the values mattered, so pointing the build at a different libquil after the first build silently kept linking the old one until a manual cargo clean. Read them with env::var at runtime and emit cargo:rerun-if-env-changed for each, so a changed value re-runs the build script. Also fix the rerun-on-header-change directive, which was spelled cargo:rustc-rerun-if-changed -- not a directive cargo recognizes, so a modified libquil.h did not trigger a rebuild of the bindings. Co-Authored-By: Claude Opus 5 (1M context) --- lib/build.rs | 37 ++++++++++++++++++++++++++----------- lib/src/lib.rs | 4 +++- lib/src/quilc.rs | 18 ++++++------------ lib/src/qvm.rs | 18 ++++++------------ 4 files changed, 41 insertions(+), 36 deletions(-) diff --git a/lib/build.rs b/lib/build.rs index 82c2dbd..d95bdd9 100644 --- a/lib/build.rs +++ b/lib/build.rs @@ -16,16 +16,29 @@ enum Error { InvalidEnvvar(#[from] env::VarError), } +/// Environment variables that select a libquil installation. They are read when the +/// build script *runs*, so changing one takes effect without a manual `cargo clean`; +/// `cargo:rerun-if-env-changed` is what makes cargo re-run us when they change. +const PATH_ENVVARS: [&str; 3] = ["LIBQUIL_SRC_PATH", "LIBQUIL_LIB_PATH", "C_INCLUDE_PATH"]; + +/// The value of `name`, or `None` when it is unset or empty. An empty value is +/// treated as unset so that `LIBQUIL_SRC_PATH= cargo build` does not put the +/// current directory at the front of the search order. +fn env_path(name: &str) -> Option { + env::var(name).ok().filter(|value| !value.is_empty()) +} + fn get_header_path() -> Result { - let mut paths = vec!["/usr/local/include/libquil", "/usr/include/libquil"]; + let mut paths = vec![ + "/usr/local/include/libquil".to_string(), + "/usr/include/libquil".to_string(), + ]; - let libquil_src_path: Option<&'static str> = option_env!("LIBQUIL_SRC_PATH"); - if let Some(libquil_src_path) = libquil_src_path { + if let Some(libquil_src_path) = env_path("LIBQUIL_SRC_PATH") { paths.insert(0, libquil_src_path); } - let c_include_path: Option<&'static str> = option_env!("C_INCLUDE_PATH"); - if let Some(c_include_path) = c_include_path { + if let Some(c_include_path) = env_path("C_INCLUDE_PATH") { paths.insert(0, c_include_path); } @@ -44,13 +57,11 @@ fn get_lib_search_paths() -> Vec { // For installs that do not use /usr/local, where the headers and libraries live // in separate directories and LIBQUIL_SRC_PATH names only the former. - let libquil_lib_path: Option<&'static str> = option_env!("LIBQUIL_LIB_PATH"); - if let Some(libquil_lib_path) = libquil_lib_path { - paths.insert(0, libquil_lib_path.to_string()); + if let Some(libquil_lib_path) = env_path("LIBQUIL_LIB_PATH") { + paths.insert(0, libquil_lib_path); } - let libquil_src_path: Option<&'static str> = option_env!("LIBQUIL_SRC_PATH"); - if let Some(libquil_src_path) = libquil_src_path { + if let Some(libquil_src_path) = env_path("LIBQUIL_SRC_PATH") { // libquil is a FASL library loaded into the libsbcl_librarian runtime, so // both must be found. A source tree keeps the runtime in a subdirectory; // an installed layout puts everything in one directory. @@ -84,6 +95,10 @@ fn main() { } fn build() -> Result<(), Error> { + for envvar in PATH_ENVVARS { + println!("cargo:rerun-if-env-changed={envvar}"); + } + let libquil_header_path = get_header_path()?; for path in get_lib_search_paths() { @@ -97,7 +112,7 @@ fn build() -> Result<(), Error> { // Tell cargo to rerun if the libquil implementation has changed println!( - "cargo:rustc-rerun-if-changed={}", + "cargo:rerun-if-changed={}", libquil_header_path.clone().display() ); diff --git a/lib/src/lib.rs b/lib/src/lib.rs index 7cfe1a2..cd63045 100644 --- a/lib/src/lib.rs +++ b/lib/src/lib.rs @@ -70,7 +70,9 @@ pub(crate) fn handle_libquil_error(errno: lisp_err_t) -> Result<(), String> { } } -pub(crate) fn get_string_from_pointer_and_free(ptr: *mut std::os::raw::c_char) -> Result { +pub(crate) fn get_string_from_pointer_and_free( + ptr: *mut std::os::raw::c_char, +) -> Result { unsafe { let s = CStr::from_ptr(ptr).to_str()?.to_string(); libc::free(ptr as *mut _); diff --git a/lib/src/quilc.rs b/lib/src/quilc.rs index 2b1d877..2b7ac51 100644 --- a/lib/src/quilc.rs +++ b/lib/src/quilc.rs @@ -138,10 +138,8 @@ impl Program { unsafe { let mut program_string_ptr: *mut std::os::raw::c_char = std::ptr::null_mut(); - let err = quilc_program_string( - self.0, - std::ptr::addr_of_mut!(program_string_ptr) as *mut _, - ); + let err = + quilc_program_string(self.0, std::ptr::addr_of_mut!(program_string_ptr) as *mut _); crate::handle_libquil_error(err).map_err(Error::ProgramString)?; let program_string = get_string_from_pointer_and_free(program_string_ptr)?; Ok(program_string) @@ -453,17 +451,13 @@ pub fn get_version_info() -> Result { crate::handle_libquil_error(err).map_err(Error::PrintProgram)?; let mut version_ptr: *mut std::os::raw::c_char = std::ptr::null_mut(); - let err = quilc_version_info_version( - version_info, - std::ptr::addr_of_mut!(version_ptr) as *mut _, - ); + let err = + quilc_version_info_version(version_info, std::ptr::addr_of_mut!(version_ptr) as *mut _); crate::handle_libquil_error(err).map_err(Error::PrintProgram)?; let mut githash_ptr: *mut std::os::raw::c_char = std::ptr::null_mut(); - let err = quilc_version_info_githash( - version_info, - std::ptr::addr_of_mut!(githash_ptr) as *mut _, - ); + let err = + quilc_version_info_githash(version_info, std::ptr::addr_of_mut!(githash_ptr) as *mut _); crate::handle_libquil_error(err).map_err(Error::PrintProgram)?; let version = get_string_from_pointer_and_free(version_ptr)?; diff --git a/lib/src/qvm.rs b/lib/src/qvm.rs index a27b8b4..945f057 100644 --- a/lib/src/qvm.rs +++ b/lib/src/qvm.rs @@ -54,17 +54,13 @@ pub fn get_version_info() -> Result { crate::handle_libquil_error(err).map_err(Error::VersionInfo)?; let mut version_ptr: *mut std::os::raw::c_char = std::ptr::null_mut(); - let err = qvm_version_info_version( - version_info, - std::ptr::addr_of_mut!(version_ptr) as *mut _, - ); + let err = + qvm_version_info_version(version_info, std::ptr::addr_of_mut!(version_ptr) as *mut _); crate::handle_libquil_error(err).map_err(Error::VersionInfo)?; let mut githash_ptr: *mut std::os::raw::c_char = std::ptr::null_mut(); - let err = qvm_version_info_githash( - version_info, - std::ptr::addr_of_mut!(githash_ptr) as *mut _, - ); + let err = + qvm_version_info_githash(version_info, std::ptr::addr_of_mut!(githash_ptr) as *mut _); crate::handle_libquil_error(err).map_err(Error::VersionInfo)?; let version = get_string_from_pointer_and_free(version_ptr)?; @@ -95,10 +91,8 @@ impl TryFrom> for QvmMultishotAddresses let name_ptr = CString::new(name.clone())?.into_raw(); match address { MultishotAddressRequest::All => { - let err = bindings::qvm_multishot_addresses_set_all( - addresses_ptr, - name_ptr, - ); + let err = + bindings::qvm_multishot_addresses_set_all(addresses_ptr, name_ptr); handle_libquil_error(err).map_err(Error::MultishotAddresses)?; } MultishotAddressRequest::Indices(indices) => { From d8435d14f8935fac11b2f8aab917212cc5a53d1e Mon Sep 17 00:00:00 2001 From: BatmanAoD Date: Wed, 12 Aug 2026 15:51:36 +0000 Subject: [PATCH 8/9] chore: prepare new release(s) [skip ci] --- Cargo.lock | 2 +- lib/CHANGELOG.md | 10 ++++++++++ lib/Cargo.toml | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4cb8738..e5f2b2c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -434,7 +434,7 @@ checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] name = "libquil-sys" -version = "0.5.0-rc.1" +version = "0.5.0-rc.2" dependencies = [ "assert2", "bindgen", diff --git a/lib/CHANGELOG.md b/lib/CHANGELOG.md index b6742a4..d4bd998 100644 --- a/lib/CHANGELOG.md +++ b/lib/CHANGELOG.md @@ -1,3 +1,13 @@ +## 0.5.0-rc.2 (2026-08-12) + +### Breaking Changes + +- build against libquil on modern sbcl-librarian + +### Fixes + +- read libquil path envvars at build-script runtime + ## 0.5.0-rc.1 (2026-08-12) ### Breaking Changes diff --git a/lib/Cargo.toml b/lib/Cargo.toml index e7bdc1a..1467474 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "libquil-sys" description = "High-level bindings to libquil" -version = "0.5.0-rc.1" +version = "0.5.0-rc.2" edition = "2021" license = "Apache-2.0" repository = "https://github.com/rigetti/libquil-sys" From 665f5800bdbf6ad8d45911222cfc544805052752 Mon Sep 17 00:00:00 2001 From: Kyle J Strand Date: Thu, 13 Aug 2026 11:45:20 -0600 Subject: [PATCH 9/9] ci: test against the libquil prerelease from rigetti/libquil The prerelease carrying the sbcl-librarian runtime is now published from rigetti/libquil itself (v0.4.0-rc.0, built by its own CI), so the fork it was coming from is going away. Drop the two repository overrides, and take install.sh from the tag being installed rather than from a branch, so the installer always matches the release it unpacks. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/test.yml | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0b7d4f1..f75ca76 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,16 +11,11 @@ env: # sbcl-librarian changed its C ABI and the set of files it installs, so this crate # needs a release from after that change: 0.3.x installs neither the runtime # headers nor libsbcl_librarian, and the build fails in build.rs. - LIBQUIL_VERSION: "0.4.0-rc.1" - # install.sh is fetched from this ref of libquil. It has to match the release + LIBQUIL_VERSION: "0.4.0-rc.0" + # install.sh is fetched from the tag being installed. It has to match the release # above: the installer that ships with a release knows which files that release # contains, and the modern-sbcl-librarian layout added the runtime directory. - LIBQUIL_INSTALL_REF: "sbcl-librarian-runtime" - # Temporary, until the libquil change is merged and released from rigetti/libquil: - # the prerelease with the new ABI is published from a fork, and install.sh has to - # be fetched from the same place so it knows which files that release contains. - LIBQUIL_INSTALL_REPO: "BatmanAoD/libquil" - LIBQUIL_RELEASE_REPO: "BatmanAoD/libquil" + LIBQUIL_INSTALL_REF: "v0.4.0-rc.0" jobs: test-linux: @@ -36,7 +31,7 @@ jobs: - uses: dtolnay/rust-toolchain@stable - name: Install libquil run: | - curl https://raw.githubusercontent.com/$LIBQUIL_INSTALL_REPO/$LIBQUIL_INSTALL_REF/install.sh | bash -s $LIBQUIL_VERSION + curl https://raw.githubusercontent.com/rigetti/libquil/$LIBQUIL_INSTALL_REF/install.sh | bash -s $LIBQUIL_VERSION - name: Run tests run: | cd $GITHUB_WORKSPACE/lib @@ -53,7 +48,7 @@ jobs: run: brew install lapack openblas - uses: dtolnay/rust-toolchain@stable - name: Install libquil - run: 'curl https://raw.githubusercontent.com/$LIBQUIL_INSTALL_REPO/$LIBQUIL_INSTALL_REF/install.sh | bash -s $LIBQUIL_VERSION' + run: 'curl https://raw.githubusercontent.com/rigetti/libquil/$LIBQUIL_INSTALL_REF/install.sh | bash -s $LIBQUIL_VERSION' - name: Run tests run: | cd $GITHUB_WORKSPACE/lib