diff --git a/.github/workflows/build-qrmi-bins.yml b/.github/workflows/build-qrmi-bins.yml index 50ad870..e607608 100644 --- a/.github/workflows/build-qrmi-bins.yml +++ b/.github/workflows/build-qrmi-bins.yml @@ -1,4 +1,6 @@ --- +# SPDX-License-Identifier: Apache-2.0 +# (C) Copyright IBM Corporation 2026 # This reusable workflow builds the QRMI binaries. # # Workflow inputs: @@ -25,9 +27,6 @@ jobs: - name: Setup Rust toolchain uses: actions-rust-lang/setup-rust-toolchain@v1 - - name: Build task_runner - run: cargo build --bin task_runner --release --features="build-binary" - - - name: Build stubgen - run: cargo build --bin stubgen --release --features="pyo3" + - name: Build task_runner and stubgen + run: make build-bins diff --git a/.github/workflows/dist.yml b/.github/workflows/dist.yml new file mode 100644 index 0000000..ec9e5cc --- /dev/null +++ b/.github/workflows/dist.yml @@ -0,0 +1,38 @@ +--- +# SPDX-License-Identifier: Apache-2.0 +# (C) Copyright IBM Corporation 2026 +# This reusable workflow creates the source code tarball and the vendor tarball. +# It is intended to be called before packaging jobs (RPM, .deb) so that tarballs +# are built once and shared across all packaging jobs via the qrmi-dist artifact. +# +# Workflow inputs: +# - None +# +# Workflow artifacts produced: +# - [uploaded] qrmi-dist (qrmi-{version}.tar.gz, qrmi-{version}-vendor.tar.gz) +# +# Workflow dependencies: +# - None. It does not depend on any other workflow. +name: Create source and vendor tarballs +on: + workflow_call: +jobs: + dist: + runs-on: ubuntu-24.04 + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Rust toolchain + uses: actions-rust-lang/setup-rust-toolchain@v1 + + - name: Create source and vendor tarballs + run: make dist + + - name: Upload tarballs + uses: actions/upload-artifact@v4 + with: + name: qrmi-dist + path: /tmp/qrmi-*.tar.gz + if-no-files-found: error + retention-days: 1 diff --git a/.github/workflows/package-deb.yml b/.github/workflows/package-deb.yml new file mode 100644 index 0000000..f536530 --- /dev/null +++ b/.github/workflows/package-deb.yml @@ -0,0 +1,98 @@ +--- +# SPDX-License-Identifier: Apache-2.0 +# (C) Copyright IBM Corporation 2026 +# This reusable workflow builds Debian packages for a given Linux distribution and version. +# It is intended to be called on release/tag events, not on pull requests. +# +# It produces: +# - libqrmi .deb (libqrmi.so) +# - libqrmi-dev .deb (libqrmi.a + qrmi.h) +# +# The QRMI version is read from Cargo.toml (single source of truth) and used +# to update packaging/debian/changelog before building. +# +# Workflow inputs: +# - [required] distro: short distro name used in artifact names (e.g. debian, ubuntu) +# - [required] distro-version: OS version name or number (e.g. bookworm, 24.04) +# - [required] container-image: full container image reference (e.g. debian:bookworm, ubuntu:24.04) +# +# Workflow artifacts produced: +# - [uploaded] qrmi-debs-{distro}{distro-version} (*.deb) +# +# Workflow dependencies: +# - None. It does not depend on any other workflow. +# +# Example caller (release workflow): +# +# package-debian-bookworm: +# uses: ./.github/workflows/package-deb.yml +# with: +# distro: debian +# distro-version: bookworm +# container-image: debian:bookworm +# +# package-ubuntu-2404: +# uses: ./.github/workflows/package-deb.yml +# with: +# distro: ubuntu +# distro-version: "24.04" +# container-image: ubuntu:24.04 +name: Package .deb for Debian and Ubuntu +on: + workflow_call: + inputs: + distro: + description: >- + Short distro name used in artifact names (e.g. debian, ubuntu) + type: string + required: true + distro-version: + description: >- + OS version name or number (e.g. bookworm, 24.04) + type: string + required: true + container-image: + description: >- + Full container image reference (e.g. debian:bookworm, ubuntu:24.04) + type: string + required: true +env: + CARGO_TERM_COLOR: always + DEBIAN_FRONTEND: noninteractive +jobs: + package: + runs-on: ubuntu-24.04 + container: + image: ${{ inputs.container-image }} + steps: + - name: Install minimal bootstrap dependencies + run: | + apt-get update -y + apt-get install -y \ + curl \ + git \ + devscripts \ + equivs + + - name: Checkout + uses: actions/checkout@v4 + + # Use debian/control as the single source of truth for build dependencies. + # This ensures the CI environment always matches what dpkg-buildpackage requires. + - name: Install build dependencies from debian/control + run: mk-build-deps --install --remove --tool "apt-get -y" packaging/debian/control + + - name: Setup Rust toolchain + uses: actions-rust-lang/setup-rust-toolchain@v1 + + - name: Build Debian packages + run: make deb + + - name: Upload .deb packages + uses: actions/upload-artifact@v4 + if: ${{ success() }} + with: + name: qrmi-debs-${{ inputs.distro }}${{ inputs.distro-version }} + path: ../*.deb + if-no-files-found: error + retention-days: 30 diff --git a/.github/workflows/package-rpm.yml b/.github/workflows/package-rpm.yml new file mode 100644 index 0000000..e7bff55 --- /dev/null +++ b/.github/workflows/package-rpm.yml @@ -0,0 +1,125 @@ +--- +# SPDX-License-Identifier: Apache-2.0 +# (C) Copyright IBM Corporation 2026 +# This reusable workflow builds RPM packages for a given Linux distribution and version. +# It is intended to be called on release/tag events, not on pull requests. +# For building the project on pull requests, use build-rpm.yml instead. +# +# It produces: +# - qrmi RPM (libqrmi.so) +# - qrmi-devel RPM (libqrmi.a + qrmi.h) +# +# The QRMI version is read from Cargo.toml (single source of truth) and passed +# to rpmbuild via --define so the generated RPM metadata matches exactly. +# +# Workflow inputs: +# - [required] distro: short distro name used in artifact names (e.g. almalinux, rockylinux, centos) +# - [required] distro-version: OS major version (e.g. 8, 9) +# - [required] container-image: full container image reference (e.g. almalinux:8, quay.io/centos/centos:stream9) +# +# Workflow artifacts produced: +# - [uploaded] qrmi-rpms-{distro}{distro-version} (*.rpm) +# +# Workflow dependencies: +# - None. It does not depend on any other workflow. +# +# Example caller (release workflow): +# +# package-almalinux8: +# uses: ./.github/workflows/package-rpm.yml +# with: +# distro: almalinux +# distro-version: "8" +# container-image: almalinux:8 +# +# package-centos9: +# uses: ./.github/workflows/package-rpm.yml +# with: +# distro: centos +# distro-version: "9" +# container-image: quay.io/centos/centos:stream9 +name: Package RPMs for AlmaLinux, Rocky Linux and CentOS +on: + workflow_call: + inputs: + distro: + description: >- + Short distro name used in artifact names (e.g. almalinux, rockylinux, centos) + type: string + required: true + distro-version: + description: >- + Major OS version to build for (e.g. 8, 9) + type: string + required: true + container-image: + description: >- + Full container image reference (e.g. almalinux:8, quay.io/centos/centos:stream9) + type: string + required: true +env: + CARGO_TERM_COLOR: always +jobs: + package: + runs-on: ubuntu-24.04 + container: + image: ${{ inputs.container-image }} + steps: + - name: Install minimal bootstrap dependencies + run: | + dnf install -y \ + curl \ + git \ + rpm-build + + - name: Checkout + uses: actions/checkout@v4 + + # Use the spec file as the single source of truth for build dependencies. + # This ensures the CI environment always matches what rpmbuild requires. + - name: Install RPM build dependencies from qrmi.spec + run: dnf builddep -y packaging/rpm/qrmi.spec + + - name: Setup Rust toolchain + uses: actions-rust-lang/setup-rust-toolchain@v1 + + # Extract the version from Cargo.toml so that Cargo.toml is the single + # source of truth for the QRMI version used in the RPM metadata. + - name: Extract QRMI version from Cargo.toml + id: qrmi-version + run: | + VERSION=$(grep -m1 '^version' Cargo.toml | sed 's/.*"\(.*\)".*/\1/') + echo "value=${VERSION}" >> "${GITHUB_OUTPUT}" + + - name: Download source and vendor tarballs + uses: actions/download-artifact@v4 + with: + name: qrmi-dist + path: /tmp + + - name: Set up rpmbuild tree + env: + QRMI_VERSION: ${{ steps.qrmi-version.outputs.value }} + run: | + set -e + mkdir -p ~/rpmbuild/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS} + cp /tmp/qrmi-${QRMI_VERSION}.tar.gz ~/rpmbuild/SOURCES/ + cp /tmp/qrmi-${QRMI_VERSION}-vendor.tar.gz ~/rpmbuild/SOURCES/ + cp packaging/rpm/qrmi.spec ~/rpmbuild/SPECS/ + + - name: Build RPMs + run: | + . "$HOME/.cargo/env" + rpmbuild -ba \ + --define "version ${{ steps.qrmi-version.outputs.value }}" \ + --define "dist .el${{ inputs.distro-version }}" \ + ~/rpmbuild/SPECS/qrmi.spec + + - name: Upload RPMs + uses: actions/upload-artifact@v4 + if: ${{ success() }} + with: + name: qrmi-rpms-${{ inputs.distro }}${{ inputs.distro-version }} + path: ~/rpmbuild/RPMS/**/*.rpm + if-no-files-found: error + retention-days: 30 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..4e96255 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,103 @@ +--- +# SPDX-License-Identifier: Apache-2.0 +# (C) Copyright IBM Corporation 2026 +# This workflow builds and publishes RPM and Debian packages on release/tag events. +# +# Workflow inputs: +# - None (triggered by tag push matching v*.*.*) +# +# Workflow artifacts produced: +# - qrmi-dist source and vendor tarballs +# - qrmi-rpms-* artifacts for each RPM-based distro/version combination +# - qrmi-debs-* artifacts for each Debian-based distro/version combination +name: Release +on: + push: + tags: + - "v*.*.*" +jobs: + dist: + name: Create source and vendor tarballs + uses: ./.github/workflows/dist.yml + + package-almalinux8: + name: Package RPMs for AlmaLinux 8 + needs: dist + uses: ./.github/workflows/package-rpm.yml + with: + distro: almalinux + distro-version: "8" + container-image: almalinux:8 + + package-almalinux9: + name: Package RPMs for AlmaLinux 9 + needs: dist + uses: ./.github/workflows/package-rpm.yml + with: + distro: almalinux + distro-version: "9" + container-image: almalinux:9 + + package-rockylinux8: + name: Package RPMs for Rocky Linux 8 + needs: dist + uses: ./.github/workflows/package-rpm.yml + with: + distro: rockylinux + distro-version: "8" + container-image: rockylinux:8 + + package-rockylinux9: + name: Package RPMs for Rocky Linux 9 + needs: dist + uses: ./.github/workflows/package-rpm.yml + with: + distro: rockylinux + distro-version: "9" + container-image: rockylinux:9 + + package-centos8: + name: Package RPMs for CentOS Stream 8 + needs: dist + uses: ./.github/workflows/package-rpm.yml + with: + distro: centos + distro-version: "8" + container-image: quay.io/centos/centos:stream8 + + package-centos9: + name: Package RPMs for CentOS Stream 9 + needs: dist + uses: ./.github/workflows/package-rpm.yml + with: + distro: centos + distro-version: "9" + container-image: quay.io/centos/centos:stream9 + + package-debian-bookworm: + name: Package .deb for Debian Bookworm + needs: dist + uses: ./.github/workflows/package-deb.yml + with: + distro: debian + distro-version: bookworm + container-image: debian:bookworm + + package-ubuntu-2204: + name: Package .deb for Ubuntu 22.04 + needs: dist + uses: ./.github/workflows/package-deb.yml + with: + distro: ubuntu + distro-version: "22.04" + container-image: ubuntu:22.04 + + package-ubuntu-2404: + name: Package .deb for Ubuntu 24.04 + needs: dist + uses: ./.github/workflows/package-deb.yml + with: + distro: ubuntu + distro-version: "24.04" + container-image: ubuntu:24.04 + diff --git a/.github/workflows/unittest-rust.yml b/.github/workflows/unittest-rust.yml index 67e1cd4..25f7178 100644 --- a/.github/workflows/unittest-rust.yml +++ b/.github/workflows/unittest-rust.yml @@ -25,22 +25,10 @@ jobs: uses: actions-rust-lang/setup-rust-toolchain@v1 - name: Unittest libqrmi.so (includes examples) - run: cargo test --all-targets --release + run: make test-libqrmi - - name: Unittest task_runner - run: cargo test --bin task_runner --release --features="build-binary" + - name: Unittest binaries + run: make test-bins - - name: Unittest stubgen - run: cargo test --bin stubgen --release --features="pyo3" - - - name: Unittest direct_access_client - working-directory: dependencies/direct_access_client - run: cargo test --release - - - name: Unittest pasqal_cloud_client - working-directory: dependencies/pasqal_cloud_client - run: cargo test --release - - - name: Unittest qiskit_runtime_client - working-directory: dependencies/qiskit_runtime_client - run: cargo test --release + - name: Unittest dependencies + run: make test-dependencies diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..683b473 --- /dev/null +++ b/Makefile @@ -0,0 +1,164 @@ +# SPDX-License-Identifier: Apache-2.0 +# (C) Copyright IBM Corporation 2026 + +include Makefile.helpers + +VERSION := $(shell grep -m1 '^version' Cargo.toml | sed 's/.*"\(.*\)".*/\1/') +DIST_DIR ?= /tmp + +.PHONY: all build build-bins build-examples build-wheels install-wheels venv fmt fmt-wheels lint lint-bins lint-rust lint-wheels test-rust test-libqrmi test-bins test-dependencies test-wheels deps-rpm deps-deb dist rpm deb clean help + +all: build + +# ------------------------------------------------ +# Rust targets +# ------------------------------------------------ + +build: + cargo build --locked --release + +build-bins: + cargo build --bin task_runner --release --features="build-binary" + cargo build --bin stubgen --release --features="pyo3" + +build-examples: + cargo build --examples --locked --release + +# Format check libqrmi, dependencies, examples and binaries +fmt: check-rustfmt + cargo fmt --all -- --check --verbose + +lint: check-clippy + cargo clippy --all-targets -- -D warnings + +lint-bins: check-clippy + cargo clippy --bin task_runner --features="build-binary" -- -D warnings + cargo clippy --bin stubgen --features="pyo3" -- -D warnings + +lint-rust: lint lint-bins + +test-libqrmi: + cargo test --locked --all-targets --release + +test-bins: + cargo test --locked --bin task_runner --release --features="build-binary" + cargo test --locked --bin stubgen --release --features="pyo3" + +test-dependencies: + cargo test --locked --release -p direct-access-api + cargo test --locked --release -p pasqal-cloud-api + cargo test --locked --release -p qiskit_runtime_client + +test-rust: test-libqrmi test-bins test-dependencies + +# ------------------------------------------------ +# Python targets +# ------------------------------------------------ + +venv: + python3 -m venv .venv + .venv/bin/pip install --upgrade pip + .venv/bin/pip install -r requirements-dev.txt + @echo "Virtual environment created. You can activate it with: source .venv/bin/activate" + +build-wheels: + maturin build --release + +fmt-wheels: check-venv + .venv/bin/black --check ./python + +install-wheels: check-venv build-wheels + .venv/bin/pip install --force-reinstall target/wheels/qrmi-*.whl + +lint-wheels: install-wheels + .venv/bin/pylint ./python + +test-wheels: install-wheels + .venv/bin/pytest python/tests/ + +# ------------------------------------------------ +# Packaging targets +# ------------------------------------------------ + +dist: + git archive --format=tar.gz \ + --prefix=qrmi-$(VERSION)/ \ + HEAD \ + -o $(DIST_DIR)/qrmi-$(VERSION).tar.gz + cargo vendor vendor + tar czf $(DIST_DIR)/qrmi-$(VERSION)-vendor.tar.gz vendor/ + +rpm: dist + mkdir -p ~/rpmbuild/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS} + cp $(DIST_DIR)/qrmi-$(VERSION).tar.gz ~/rpmbuild/SOURCES/ + cp $(DIST_DIR)/qrmi-$(VERSION)-vendor.tar.gz ~/rpmbuild/SOURCES/ + cp packaging/rpm/qrmi.spec ~/rpmbuild/SPECS/ + rpmbuild -ba \ + --define "version $(VERSION)" \ + ~/rpmbuild/SPECS/qrmi.spec + +deb: dist + ln -sfn packaging/debian debian + dch --newversion $(VERSION)-1 --distribution unstable \ + --force-distribution "Release $(VERSION)" + dpkg-buildpackage -us -uc -b + rm -f debian + +# ------------------------------------------------ +# Setup targets +# ------------------------------------------------ + +deps-rpm: check-root check-rpm-distro + dnf builddep -y packaging/rpm/qrmi.spec + +deps-deb: check-root check-deb-distro + mk-build-deps --install --remove packaging/debian/control + +# ------------------------------------------------ +# Misc targets +# ------------------------------------------------ + +clean: + cargo clean + +help: + @echo "Rust targets:" + @echo + @echo " all - Build the project (default)" + @echo " build - Build libqrmi" + @echo " build-bins - Build task_runner and stubgen binaries" + @echo " build-examples - Build Rust examples" + @echo " test-rust - Run all Rust unit tests" + @echo " test-libqrmi - Run Rust unit tests for libqrmi" + @echo " test-bins - Run Rust unit tests for task_runner and stubgen binaries" + @echo " test-dependencies - Run Rust unit tests for direct_access_client, pasqal_cloud_client and qiskit_runtime_client" + @echo " lint-rust - Run all Rust lints (lint + lint-bins)" + @echo " lint - Lint libqrmi, dependencies and examples" + @echo " lint-bins - Lint task_runner and stubgen binaries" + @echo " fmt - Check Rust code formatting for all targets" + @echo + @echo "Python targets:" + @echo + @echo " build-wheels - Build Python wheels using maturin" + @echo " install-wheels - Install wheels into .venv" + @echo " venv - Create .venv and install requirements-dev.txt" + @echo " fmt-wheels - Check Python code formatting using black" + @echo " lint-wheels - Lint Python code using pylint" + @echo " test-wheels - Run Python unit tests" + @echo + @echo "Packaging targets:" + @echo + @echo " dist - Create source and vendor tarballs in DIST_DIR (default: /tmp)" + @echo " rpm - Build RPM packages (requires dist tarballs in DIST_DIR)" + @echo " deb - Build Debian packages (.deb)" + @echo + @echo "Setup targets:" + @echo + @echo " deps-rpm - Install RPM build dependencies from packaging/rpm/qrmi.spec" + @echo " deps-deb - Install Debian build dependencies from packaging/debian/control" + @echo + @echo "Misc targets:" + @echo + @echo " clean - Remove build artifacts" + @echo " help - Show this help message" + \ No newline at end of file diff --git a/Makefile.helpers b/Makefile.helpers new file mode 100644 index 0000000..0582995 --- /dev/null +++ b/Makefile.helpers @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: Apache-2.0 +# (C) Copyright IBM Corporation 2026 + +.PHONY: check-root check-rpm-distro check-deb-distro check-venv check-rustfmt check-clippy + +check-root: + @if [ "$$(id -u)" -ne 0 ]; then \ + echo "Error: this target must be run as root (e.g. sudo make $(MAKECMDGOALS))"; \ + exit 1; \ + fi + +check-rpm-distro: + @command -v rpm >/dev/null 2>&1 || \ + { echo "Error: this target requires an RPM-based distribution (e.g. RHEL, AlmaLinux, Rocky Linux)"; exit 1; } + +check-deb-distro: + @command -v dpkg >/dev/null 2>&1 || \ + { echo "Error: this target requires a Debian-based distribution (e.g. Debian, Ubuntu)"; exit 1; } + +check-venv: + @[ -d .venv ] || { echo "Error: .venv not found. Run: make venv"; exit 1; } + +check-rustfmt: + @rustup component list --installed 2>/dev/null | grep -q '^rustfmt' || \ + { echo "Error: rustfmt is not installed. Run: rustup component add rustfmt"; exit 1; } + +check-clippy: + @rustup component list --installed 2>/dev/null | grep -q '^clippy' || \ + { echo "Error: clippy is not installed. Run: rustup component add clippy"; exit 1; } \ No newline at end of file diff --git a/packaging/debian/changelog b/packaging/debian/changelog new file mode 100644 index 0000000..1fa82e6 --- /dev/null +++ b/packaging/debian/changelog @@ -0,0 +1,5 @@ +qrmi (0.11.0-1) unstable; urgency=medium + + * Initial Debian packaging. + + -- Claudio Carvalho Fri, 28 Feb 2026 00:00:00 +0000 \ No newline at end of file diff --git a/packaging/debian/control b/packaging/debian/control new file mode 100644 index 0000000..8f68b31 --- /dev/null +++ b/packaging/debian/control @@ -0,0 +1,36 @@ +Source: qrmi +Section: libs +Priority: optional +Maintainer: IBM, Pasqal SAS and UKRI-STFC (Hartree Centre) +Build-Depends: debhelper-compat (= 13), + gcc, + g++, + make, + cmake, + libssl-dev, + zlib1g-dev, + pkg-config +Standards-Version: 4.6.2 +Homepage: https://github.com/qiskit-community/spank-plugins +Rules-Requires-Root: no + +# Rust toolchain is installed via rustup and is not a Debian build dependency. +# Ensure `cargo` and `rustc` >= 1.91 are available in PATH before building. + +Package: libqrmi +Architecture: any +Multi-Arch: same +Depends: ${shlibs:Depends}, ${misc:Depends} +Description: Quantum Resource Management Interface (QRMI) + QRMI is a set of libraries that provide a unified interface to control + the state of quantum resources. It exposes a C API (libqrmi.so / qrmi.h) + and a Python API built on top of the same Rust core. + +Package: libqrmi-dev +Architecture: any +Multi-Arch: same +Section: libdevel +Depends: libqrmi (= ${binary:Version}), ${misc:Depends} +Description: Development files for libqrmi + Header file (qrmi.h) and static library (libqrmi.a) for building + applications against the QRMI C API. \ No newline at end of file diff --git a/packaging/debian/copyright b/packaging/debian/copyright new file mode 100644 index 0000000..0c14576 --- /dev/null +++ b/packaging/debian/copyright @@ -0,0 +1,24 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: qrmi +Upstream-Contact: IBM, Pasqal SAS and UKRI-STFC (Hartree Centre) +Source: https://github.com/qiskit-community/spank-plugins + +Files: * +Copyright: IBM, Pasqal SAS and UKRI-STFC (Hartree Centre) +License: Apache-2.0 + +License: Apache-2.0 + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + . + https://www.apache.org/licenses/LICENSE-2.0 + . + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + . + On Debian systems, the full text of the Apache License, Version 2.0 + can be found in the file `/usr/share/common-licenses/Apache-2.0'. \ No newline at end of file diff --git a/packaging/debian/rules b/packaging/debian/rules new file mode 100644 index 0000000..9995aa6 --- /dev/null +++ b/packaging/debian/rules @@ -0,0 +1,40 @@ +#!/usr/bin/make -f +# SPDX-License-Identifier: Apache-2.0 +# (C) Copyright IBM Corporation 2026 + +export DH_VERBOSE = 1 +export CARGO_HOME = $(CURDIR)/.cargo-home + +%: + dh $@ + +override_dh_auto_build: + [ -f "$$HOME/.cargo/env" ] && . "$$HOME/.cargo/env"; \ + cargo build --locked --release + +override_dh_auto_install: + install -d debian/libqrmi/usr/lib + install -d debian/libqrmi-dev/usr/lib + install -d debian/libqrmi-dev/usr/include + + # Shared library + install -m 0755 target/release/libqrmi.so \ + debian/libqrmi/usr/lib/libqrmi.so.$(VERSION) + ln -sf libqrmi.so.$(VERSION) \ + debian/libqrmi/usr/lib/libqrmi.so.0 + ln -sf libqrmi.so.0 \ + debian/libqrmi/usr/lib/libqrmi.so + + # Static library (dev package) + install -m 0644 target/release/libqrmi.a \ + debian/libqrmi-dev/usr/lib/libqrmi.a + + # C header (dev package) + install -m 0644 qrmi.h \ + debian/libqrmi-dev/usr/include/qrmi.h + +override_dh_auto_test: + # Tests are run separately; skip here. + +override_dh_auto_clean: + cargo clean \ No newline at end of file diff --git a/packaging/rpm/qrmi.spec b/packaging/rpm/qrmi.spec new file mode 100644 index 0000000..768e6e8 --- /dev/null +++ b/packaging/rpm/qrmi.spec @@ -0,0 +1,142 @@ +# SPDX-License-Identifier: Apache-2.0 +# (C) Copyright IBM Corporation 2026 + # RPM spec file for the Quantum Resource Management Interface (QRMI) +# +# Packages produced: +# qrmi - shared library (libqrmi.so) and C header (qrmi.h) +# qrmi-devel - development files (static library + header) +# +# Build requirements: +# - Rust toolchain >= 1.91 (install via rustup; not available as an RPM on EL8/EL9) +# - cargo-vendor (bundled with cargo) +# - gcc, make, cmake, openssl-devel, zlib-devel, pkg-config +# +# Offline / air-gapped builds: +# Run the following once on a machine with internet access to create the +# vendor tarball, then place it alongside the source tarball: +# +# tar xf qrmi-%%{version}.tar.gz +# cd qrmi-%%{version} +# cargo vendor vendor +# tar czf qrmi-%%{version}-vendor.tar.gz vendor/ +# +# Usage: +# rpmbuild -ba qrmi.spec \ +# --define "_sourcedir /path/to/sources" \ +# --define "version $(grep -m1 '^version' Cargo.toml | sed 's/.*\"\(.*\)\".*/\1/')" +# +# The version is intentionally not hardcoded here. It must be supplied by the +# caller via --define so that Cargo.toml remains the single source of truth. + +%global crate qrmi + +Name: %{crate} +Version: %{version} +Release: 1%{?dist} +Summary: Quantum Resource Management Interface (QRMI) +License: Apache-2.0 +URL: https://github.com/qiskit-community/qrmi +Source0: %{crate}-%{version}.tar.gz +Source1: %{crate}-%{version}-vendor.tar.gz + +BuildRequires: gcc +BuildRequires: gcc-c++ +BuildRequires: make +BuildRequires: cmake +BuildRequires: openssl-devel +BuildRequires: zlib-devel +BuildRequires: pkg-config + +# Rust toolchain is installed via rustup and is not an RPM dependency. +# Ensure `cargo` and `rustc` >= 1.91 are available in PATH before building. + +%description +Quantum Resource Management Interface (QRMI) is a set of libraries that +provide a unified interface to control the state of quantum resources. +It exposes a C API (libqrmi.so / qrmi.h) and a Python API built on top +of the same Rust core. + +# --------------------------------------------------------------------------- +# Sub-package: devel +# --------------------------------------------------------------------------- +%package devel +Summary: Development files for %{name} +Requires: %{name}%{?_isa} = %{version}-%{release} + +%description devel +Header file (qrmi.h) and static library (libqrmi.a) for building +applications against the QRMI C API. + +# --------------------------------------------------------------------------- +# Prep +# --------------------------------------------------------------------------- +%prep +%autosetup -n %{crate}-%{version} + +# Unpack the vendored Rust dependencies +tar xf %{SOURCE1} + +# Configure Cargo to use the vendored sources (offline build) +mkdir -p .cargo +cat > .cargo/config.toml << 'EOF' +[source.crates-io] +replace-with = "vendored-sources" + +[source.vendored-sources] +directory = "vendor" +EOF + +# --------------------------------------------------------------------------- +# Build +# --------------------------------------------------------------------------- +%build +# Source the Rust environment if installed via rustup +[ -f "$HOME/.cargo/env" ] && . "$HOME/.cargo/env" + +# Build the shared library +make build + +# --------------------------------------------------------------------------- +# Install +# --------------------------------------------------------------------------- +%install +install -d %{buildroot}%{_libdir} +install -d %{buildroot}%{_includedir} + +# Shared library +install -m 0755 target/release/libqrmi.so \ + %{buildroot}%{_libdir}/libqrmi.so.%{version} +ln -sf libqrmi.so.%{version} \ + %{buildroot}%{_libdir}/libqrmi.so.0 +ln -sf libqrmi.so.0 \ + %{buildroot}%{_libdir}/libqrmi.so + +# C header (generated by cbindgen during the cargo build) +install -m 0644 qrmi.h \ + %{buildroot}%{_includedir}/qrmi.h + +# --------------------------------------------------------------------------- +# Post-install / post-uninstall ldconfig triggers +# --------------------------------------------------------------------------- +%post -p /sbin/ldconfig +%postun -p /sbin/ldconfig + +# --------------------------------------------------------------------------- +# Files +# --------------------------------------------------------------------------- +%files +%license LICENSE.txt +%doc README.md INSTALL.md +%{_libdir}/libqrmi.so.%{version} +%{_libdir}/libqrmi.so.0 + +%files devel +%{_libdir}/libqrmi.so +%{_includedir}/qrmi.h + +# --------------------------------------------------------------------------- +# Changelog +# --------------------------------------------------------------------------- +%changelog +* Fri Feb 28 2026 Claudio Carvalho 0.11.0-1 +- Initial RPM packaging \ No newline at end of file