Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
19 changes: 16 additions & 3 deletions .github/workflows/python-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ name: Python Artifacts

env:
TRIGGER_ON_PR_PUSH: true # Set to true to enable triggers on PR pushes
# Must match pecos_build::cmake::CMAKE_VERSION. The MWPF decoder feature
# uses highs-sys, which needs cmake; the wheel build installs this version
# via `pecos install cmake` and points highs-sys's cmake-rs at it via $CMAKE.
PECOS_CMAKE_VERSION: "3.31.12"

on:
push:
Expand Down Expand Up @@ -186,10 +190,12 @@ jobs:
CIBW_MANYLINUX_AARCH64_IMAGE: "manylinux_2_28"
# Linux configuration - GCC Toolset and CUDA paths are conditional via matrix variables
CIBW_ENVIRONMENT_LINUX: >
PATH=${{ matrix.gcc_path_prefix }}$HOME/.cargo/bin:$HOME/.pecos/deps/llvm-14/bin:/usr/local/cuda-12.6/bin:$PATH
PATH=${{ matrix.gcc_path_prefix }}$HOME/.cargo/bin:$HOME/.pecos/deps/llvm-14/bin:$HOME/.pecos/deps/cmake-${{ env.PECOS_CMAKE_VERSION }}/bin:/usr/local/cuda-12.6/bin:$PATH
LD_LIBRARY_PATH=${{ matrix.gcc_ld_path }}$LD_LIBRARY_PATH
LLVM_SYS_140_PREFIX=$HOME/.pecos/deps/llvm-14
CMAKE=$HOME/.pecos/deps/cmake-${{ env.PECOS_CMAKE_VERSION }}/bin/cmake
CUDA_PATH=/usr/local/cuda-12.6
MATURIN_PEP517_ARGS=--features=mwpf
CIBW_BEFORE_ALL_LINUX: |
curl -sSf https://sh.rustup.rs | sh -s -- -y
source $HOME/.cargo/env
Expand All @@ -211,20 +217,24 @@ jobs:
echo "Skipping CUDA installation (GPU support not enabled for this build)"
fi
cargo run --release -p pecos-cli -- install llvm --force
cargo run --release -p pecos-cli -- install cmake --force
CIBW_REPAIR_WHEEL_COMMAND_LINUX: >
auditwheel repair -w {dest_dir} {wheel} &&
pipx run abi3audit --strict --report {wheel}
# macOS configuration
CIBW_ENVIRONMENT_MACOS: >
PATH=$HOME/.cargo/bin:$HOME/.pecos/deps/llvm-14/bin:$PATH
PATH=$HOME/.cargo/bin:$HOME/.pecos/deps/llvm-14/bin:$HOME/.pecos/deps/cmake-${{ env.PECOS_CMAKE_VERSION }}/CMake.app/Contents/bin:$PATH
LLVM_SYS_140_PREFIX=$HOME/.pecos/deps/llvm-14
CMAKE=$HOME/.pecos/deps/cmake-${{ env.PECOS_CMAKE_VERSION }}/CMake.app/Contents/bin/cmake
MACOSX_DEPLOYMENT_TARGET=13.2
SDKROOT=$(xcrun --show-sdk-path)
MATURIN_PEP517_ARGS=--features=mwpf
CIBW_BEFORE_ALL_MACOS: |
curl -sSf https://sh.rustup.rs | sh -s -- -y
source $HOME/.cargo/env
rustup update
cargo run --release -p pecos-cli -- install llvm --force
cargo run --release -p pecos-cli -- install cmake --force
# Create a codesign wrapper that strips DYLD_LIBRARY_PATH to prevent
# crashes on macOS 15 when bundled libc++ conflicts with system libc++
mkdir -p $HOME/.pecos/bin
Expand All @@ -235,12 +245,15 @@ jobs:
pipx run abi3audit --strict --report {wheel}
# Windows configuration - CUDA via Jimver/cuda-toolkit (installed before cibuildwheel)
CIBW_ENVIRONMENT_WINDOWS: >
PATH="C:\\Users\\runneradmin\\.pecos\\deps\\llvm-14\\bin;$PATH"
PATH="C:\\Users\\runneradmin\\.pecos\\deps\\llvm-14\\bin;C:\\Users\\runneradmin\\.pecos\\deps\\cmake-${{ env.PECOS_CMAKE_VERSION }}\\bin;$PATH"
LLVM_SYS_140_PREFIX="C:\\Users\\runneradmin\\.pecos\\deps\\llvm-14"
CMAKE="C:\\Users\\runneradmin\\.pecos\\deps\\cmake-${{ env.PECOS_CMAKE_VERSION }}\\bin\\cmake.exe"
MATURIN_PEP517_ARGS=--features=mwpf
CIBW_BEFORE_ALL_WINDOWS: >
echo "=== Installing LLVM using pecos ===" &&
rustup update &&
cargo run --release -p pecos-cli -- install llvm --force &&
cargo run --release -p pecos-cli -- install cmake --force &&
echo "=== Checking LLVM installation ===" &&
(test -d "C:\\Users\\runneradmin\\.pecos\\deps\\llvm-14" && echo "LLVM directory exists") || (echo "ERROR: LLVM directory not found!" && exit 1)
# Install delvewheel and patch it to ignore ext-ms-win-* API sets
Expand Down
6 changes: 6 additions & 0 deletions .github/workflows/python-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ env:
RUST_BACKTRACE: 1
PYTHONUTF8: 1
LLVM_VERSION: "14.0.6"
# Force the MWPF decoder feature on in CI so we exercise the cmake-dependent
# build path and catch regressions. GitHub-hosted runners ship cmake.
PECOS_BUILD_MWPF: "1"

on:
push:
Expand Down Expand Up @@ -101,6 +104,9 @@ jobs:
export PATH="$HOME/.cargo/bin:$PATH"
rustup show

- name: Verify cmake is available (MWPF decoder build)
run: cmake --version

- name: Install just
uses: extractions/setup-just@v4

Expand Down
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -213,3 +213,9 @@ cython_debug/
clib/*/.venv/
clib/*/uv.lock
python/selene-plugins/*/uv.lock

# Generated Rust doc-test fixture: the crate is its own (empty) workspace
# whose only purpose is to compile extracted markdown examples. cargo test
# regenerates Cargo.lock on demand; tracking it just creates dependabot
# noise for transitive bumps that don't affect anything we ship.
python/quantum-pecos/tests/docs/rust_crate/Cargo.lock
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ tar = "0.4"
xz2 = "0.1"
bzip2 = "0.6"
sevenz-rust = "0.6"
zip = { version = "2.4", default-features = false, features = ["deflate"] }

# --- Logging ---
log = "0.4"
Expand Down
26 changes: 26 additions & 0 deletions Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,32 @@ doctor:
fi
echo ""

echo "Optional decoders:"
CMAKE_BIN=""
# Prefer PECOS-managed install (mirrors find_cmake() in pecos-build).
for d in "$HOME"/.pecos/deps/cmake-*; do
[ -d "$d" ] || continue
# macOS layout nests cmake inside CMake.app/Contents/bin/.
for candidate in "$d/CMake.app/Contents/bin/cmake" "$d/bin/cmake" "$d/bin/cmake.exe"; do
if [ -x "$candidate" ]; then
CMAKE_BIN="$candidate"
break 2
fi
done
done
if [ -z "$CMAKE_BIN" ] && command -v cmake >/dev/null 2>&1; then
CMAKE_BIN=$(command -v cmake)
fi
if [ -n "$CMAKE_BIN" ]; then
CMAKE_VER=$("$CMAKE_BIN" --version 2>/dev/null | head -1 | awk '{print $3}')
ok "cmake" "$CMAKE_VER (MWPF decoder available) at $CMAKE_BIN"
else
echo " [--] cmake: not found — MWPF decoder disabled"
echo " Install via 'pecos setup' / 'pecos install cmake', or see:"
echo " https://github.com/PECOS-packages/PECOS/blob/dev/docs/user-guide/cmake-setup.md"
fi
echo ""

if [ "$PROBLEMS" -eq 0 ]; then
echo "No problems found."
else
Expand Down
1 change: 1 addition & 0 deletions crates/pecos-build/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ flate2.workspace = true
bzip2.workspace = true
xz2.workspace = true
sevenz-rust.workspace = true
zip.workspace = true

# Error handling
thiserror.workspace = true
Expand Down
87 changes: 87 additions & 0 deletions crates/pecos-build/src/cmake.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
//! cmake detection and vendored install.
//!
//! cmake is required by the optional MWPF decoder (via the highs-sys C++ LP
//! solver). PECOS handles cmake the same way it handles LLVM: a system install
//! is the fast path, and `pecos install cmake` will fetch a vendored copy from
//! Kitware into `~/.pecos/deps/cmake-{CMAKE_VERSION}/` when none is found.

pub mod installer;

use std::path::{Path, PathBuf};
use std::process::Command;

/// cmake version PECOS vendors. Pinned to the latest 3.x release so that
/// projects with `cmake_minimum_required(VERSION 3.x)` (like `HiGHS`) keep
/// building without policy compatibility surprises from cmake 4.x.
pub const CMAKE_VERSION: &str = "3.31.12";

/// Find a usable cmake.
///
/// Search order:
/// 1. PECOS-managed install at `~/.pecos/deps/cmake-{CMAKE_VERSION}/`
/// 2. `cmake` on PATH
///
/// Returns `Some(path-to-cmake-binary)` or `None`.
#[must_use]
pub fn find_cmake() -> Option<PathBuf> {
if let Ok(vendored_root) = crate::home::get_cmake_dir_path()
&& let Some(bin) = cmake_binary_in(&vendored_root)
&& bin.is_file()
{
return Some(bin);
}
find_system_cmake()
}

/// Find cmake on the system PATH.
#[must_use]
pub fn find_system_cmake() -> Option<PathBuf> {
let output = Command::new("cmake").arg("--version").output().ok()?;
if !output.status.success() {
return None;
}
which_in_path("cmake")
}

/// Directory containing the cmake binary for a given installation root.
///
/// On Linux and Windows the layout is `{root}/bin/cmake[.exe]`. On macOS the
/// upstream tarball nests the binary inside `CMake.app/Contents/bin/`.
#[must_use]
pub fn cmake_bin_dir(root: &Path) -> PathBuf {
if cfg!(target_os = "macos") {
root.join("CMake.app").join("Contents").join("bin")
} else {
root.join("bin")
}
}

/// Path to the cmake binary inside an installation root, if it exists.
#[must_use]
pub fn cmake_binary_in(root: &Path) -> Option<PathBuf> {
let bin_name = if cfg!(windows) { "cmake.exe" } else { "cmake" };
let candidate = cmake_bin_dir(root).join(bin_name);
candidate.is_file().then_some(candidate)
}

fn which_in_path(name: &str) -> Option<PathBuf> {
let path_var = std::env::var_os("PATH")?;
let exts: &[&str] = if cfg!(windows) {
&[".exe", ".bat", ""]
} else {
&[""]
};
for dir in std::env::split_paths(&path_var) {
for ext in exts {
let candidate = dir.join(format!("{name}{ext}"));
if candidate.is_file() {
return Some(candidate);
}
}
}
None
}

/// The docs URL we point users at for manual install instructions.
pub const DOCS_URL: &str =
"https://github.com/PECOS-packages/PECOS/blob/dev/docs/user-guide/cmake-setup.md";
Loading
Loading