From 3ddb793925c3f65b0b34013348a7aff1568e3b75 Mon Sep 17 00:00:00 2001 From: P Charishma Kumari Date: Tue, 5 May 2026 11:14:58 +0530 Subject: [PATCH 01/50] Build script to build liboqs Signed-off-by: P Charishma Kumari --- README.md | 34 ++++ build_liboqs.sh | 475 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 509 insertions(+) create mode 100755 build_liboqs.sh diff --git a/README.md b/README.md index 6564c9190f..2aa9369b5a 100644 --- a/README.md +++ b/README.md @@ -107,6 +107,40 @@ This project is not commercially supported. All guidelines and goals for liboqs ### Linux and Mac +#### Option 1: Using the automated build script (Recommended) + +1. Get the source: + + git clone -b main https://github.com/open-quantum-safe/liboqs.git + cd liboqs + +2. Run the build script: + + ./build_liboqs.sh + + The script will automatically: + - Detect your operating system (macOS, Ubuntu/Debian, or NixOS) + - Install all required dependencies (including Python test dependencies on macOS with automatic pip handling) + - Configure and build liboqs with default settings + + For custom build options, see the help: + + ./build_liboqs.sh --help + + Examples: + ```bash + # Build shared library with debug symbols + ./build_liboqs.sh --shared --build-type Debug + + # Minimal build with only ML-KEM-768 and ML-DSA-44 + ./build_liboqs.sh --minimal-build "KEM_ml_kem_768;SIG_ml_dsa_44" + + # Build without OpenSSL + ./build_liboqs.sh --no-openssl + ``` + +#### Option 2: Manual installation + 1. Install dependencies: On Ubuntu: diff --git a/build_liboqs.sh b/build_liboqs.sh new file mode 100755 index 0000000000..5a811cb86c --- /dev/null +++ b/build_liboqs.sh @@ -0,0 +1,475 @@ +#!/bin/bash + +# build_liboqs.sh - Build script for liboqs with OS detection and dependency installation +# Supports runtime CMake configuration options from CONFIGURE.md + +set -e # Exit on error + +# Color codes for output +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +RED='\033[0;31m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +# Function to display usage information +usage() { + cat << EOF +Usage: $0 [OPTIONS] + +Build liboqs with optional CMake configuration options. + +OPTIONS: + -h, --help Show this help message + + Build Configuration: + --shared Build shared library (BUILD_SHARED_LIBS=ON) + --build-type TYPE Set build type: Debug, Release, MinSizeRel, RelWithDebInfo (default: Release) + --install-prefix PATH Set installation prefix (CMAKE_INSTALL_PREFIX) + + Algorithm Selection: + --algs-enabled SET Algorithm set: STD, NIST_R4, NIST_SIG_ONRAMP, All (default: All) + --minimal-build "ALG1;ALG2" Build only specified algorithms (e.g., "KEM_ml_kem_768;SIG_ml_dsa_44") + --enable-kem-ALG Enable specific KEM algorithm + --enable-sig-ALG Enable specific signature algorithm + --enable-sig-stfl-ALG Enable specific stateful signature algorithm + + Build Options: + --build-only-lib Build only library, exclude tests and docs (OQS_BUILD_ONLY_LIB=ON) + --dist-build Build for distribution (OQS_DIST_BUILD=ON, default) + --no-dist-build Build for single machine (OQS_DIST_BUILD=OFF) + --opt-target TARGET Optimization target: auto, generic, or specific CPU (default: auto) + + OpenSSL Options: + --use-openssl Use OpenSSL (OQS_USE_OPENSSL=ON, default) + --no-openssl Don't use OpenSSL (OQS_USE_OPENSSL=OFF) + --openssl-root PATH OpenSSL root directory (OPENSSL_ROOT_DIR) + --dlopen-openssl Dynamically load OpenSSL (OQS_DLOPEN_OPENSSL=ON) + + GPU Acceleration: + --use-cupqc Use NVIDIA cuPQC library (OQS_USE_CUPQC=ON) + --use-icicle Use ICICLE GPU acceleration (OQS_USE_ICICLE=ON) + + CPU Features (for non-dist builds): + --use-adx Use ADX instructions (OQS_USE_ADX_INSTRUCTIONS=ON) + --use-aes Use AES instructions (OQS_USE_AES_INSTRUCTIONS=ON) + --use-avx Use AVX instructions (OQS_USE_AVX_INSTRUCTIONS=ON) + --use-avx2 Use AVX2 instructions (OQS_USE_AVX2_INSTRUCTIONS=ON) + --use-avx512 Use AVX512 instructions (OQS_USE_AVX512_INSTRUCTIONS=ON) + + Advanced Options: + --embedded-build Build for embedded systems (OQS_EMBEDDED_BUILD=ON) + --memopt-build Use memory-optimized implementations (OQS_MEMOPT_BUILD=ON) + --libjade-build Use Libjade implementations (OQS_LIBJADE_BUILD=ON) + --strict-warnings Enable strict compiler warnings (OQS_STRICT_WARNINGS=ON) + --enable-constant-time-test Enable constant-time testing (OQS_ENABLE_TEST_CONSTANT_TIME=ON) + --use-coverage Enable code coverage (USE_COVERAGE=ON) + --use-sanitizer TYPE Enable sanitizer: Address, Memory, Undefined, Thread, Leak + + Stateful Signatures: + --enable-xmss Enable XMSS stateful signatures (OQS_ENABLE_SIG_STFL_XMSS=ON) + --enable-lms Enable LMS stateful signatures (OQS_ENABLE_SIG_STFL_LMS=ON) + --enable-stfl-key-sig-gen Enable stateful key/sig generation (HAZARDOUS, see docs) + + Custom CMake Options: + -D KEY=VALUE Pass custom CMake option directly + +EXAMPLES: + # Basic build with defaults + $0 + + # Build shared library with debug symbols + $0 --shared --build-type Debug + + # Minimal build with only ML-KEM-768 and ML-DSA-44 + $0 --minimal-build "KEM_ml_kem_768;SIG_ml_dsa_44" + + # Build for distribution with OpenSSL + $0 --dist-build --use-openssl + + # Build with GPU acceleration + $0 --use-icicle + + # Build with custom options + $0 --build-type Release --strict-warnings -DOQS_USE_AVX2_INSTRUCTIONS=ON + +For more details, see CONFIGURE.md + +EOF + exit 0 +} + +echo "========================================" +echo " liboqs Build Script" +echo "========================================" +echo "" + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# Array to store CMake options +CMAKE_OPTIONS=() + +# Parse command line arguments +while [[ $# -gt 0 ]]; do + case $1 in + -h|--help) + usage + ;; + --shared) + CMAKE_OPTIONS+=("-DBUILD_SHARED_LIBS=ON") + shift + ;; + --build-type) + CMAKE_OPTIONS+=("-DCMAKE_BUILD_TYPE=$2") + shift 2 + ;; + --install-prefix) + CMAKE_OPTIONS+=("-DCMAKE_INSTALL_PREFIX=$2") + shift 2 + ;; + --algs-enabled) + CMAKE_OPTIONS+=("-DOQS_ALGS_ENABLED=$2") + shift 2 + ;; + --minimal-build) + CMAKE_OPTIONS+=("-DOQS_MINIMAL_BUILD=$2") + shift 2 + ;; + --enable-kem-*) + ALG="${1#--enable-kem-}" + ALG_UPPER=$(echo "$ALG" | tr '[:lower:]' '[:upper:]') + CMAKE_OPTIONS+=("-DOQS_ENABLE_KEM_${ALG_UPPER}=ON") + shift + ;; + --enable-sig-*) + ALG="${1#--enable-sig-}" + ALG_UPPER=$(echo "$ALG" | tr '[:lower:]' '[:upper:]') + CMAKE_OPTIONS+=("-DOQS_ENABLE_SIG_${ALG_UPPER}=ON") + shift + ;; + --enable-sig-stfl-*) + ALG="${1#--enable-sig-stfl-}" + ALG_UPPER=$(echo "$ALG" | tr '[:lower:]' '[:upper:]') + CMAKE_OPTIONS+=("-DOQS_ENABLE_SIG_STFL_${ALG_UPPER}=ON") + shift + ;; + --build-only-lib) + CMAKE_OPTIONS+=("-DOQS_BUILD_ONLY_LIB=ON") + shift + ;; + --dist-build) + CMAKE_OPTIONS+=("-DOQS_DIST_BUILD=ON") + shift + ;; + --no-dist-build) + CMAKE_OPTIONS+=("-DOQS_DIST_BUILD=OFF") + shift + ;; + --opt-target) + CMAKE_OPTIONS+=("-DOQS_OPT_TARGET=$2") + shift 2 + ;; + --use-openssl) + CMAKE_OPTIONS+=("-DOQS_USE_OPENSSL=ON") + shift + ;; + --no-openssl) + CMAKE_OPTIONS+=("-DOQS_USE_OPENSSL=OFF") + shift + ;; + --openssl-root) + CMAKE_OPTIONS+=("-DOPENSSL_ROOT_DIR=$2") + shift 2 + ;; + --dlopen-openssl) + CMAKE_OPTIONS+=("-DOQS_DLOPEN_OPENSSL=ON") + shift + ;; + --use-cupqc) + CMAKE_OPTIONS+=("-DOQS_USE_CUPQC=ON") + shift + ;; + --use-icicle) + CMAKE_OPTIONS+=("-DOQS_USE_ICICLE=ON") + shift + ;; + --use-adx) + CMAKE_OPTIONS+=("-DOQS_USE_ADX_INSTRUCTIONS=ON") + shift + ;; + --use-aes) + CMAKE_OPTIONS+=("-DOQS_USE_AES_INSTRUCTIONS=ON") + shift + ;; + --use-avx) + CMAKE_OPTIONS+=("-DOQS_USE_AVX_INSTRUCTIONS=ON") + shift + ;; + --use-avx2) + CMAKE_OPTIONS+=("-DOQS_USE_AVX2_INSTRUCTIONS=ON") + shift + ;; + --use-avx512) + CMAKE_OPTIONS+=("-DOQS_USE_AVX512_INSTRUCTIONS=ON") + shift + ;; + --embedded-build) + CMAKE_OPTIONS+=("-DOQS_EMBEDDED_BUILD=ON") + shift + ;; + --memopt-build) + CMAKE_OPTIONS+=("-DOQS_MEMOPT_BUILD=ON") + shift + ;; + --libjade-build) + CMAKE_OPTIONS+=("-DOQS_LIBJADE_BUILD=ON") + shift + ;; + --strict-warnings) + CMAKE_OPTIONS+=("-DOQS_STRICT_WARNINGS=ON") + shift + ;; + --enable-constant-time-test) + CMAKE_OPTIONS+=("-DOQS_ENABLE_TEST_CONSTANT_TIME=ON") + shift + ;; + --use-coverage) + CMAKE_OPTIONS+=("-DUSE_COVERAGE=ON") + shift + ;; + --use-sanitizer) + CMAKE_OPTIONS+=("-DUSE_SANITIZER=$2") + shift 2 + ;; + --enable-xmss) + CMAKE_OPTIONS+=("-DOQS_ENABLE_SIG_STFL_XMSS=ON") + shift + ;; + --enable-lms) + CMAKE_OPTIONS+=("-DOQS_ENABLE_SIG_STFL_LMS=ON") + shift + ;; + --enable-stfl-key-sig-gen) + echo -e "${RED}WARNING: Enabling stateful signature key/signature generation is HAZARDOUS!${NC}" + echo -e "${RED}See CONFIGURE.md for security implications.${NC}" + CMAKE_OPTIONS+=("-DOQS_HAZARDOUS_EXPERIMENTAL_ENABLE_SIG_STFL_KEY_SIG_GEN=ON") + shift + ;; + -D*) + CMAKE_OPTIONS+=("$1") + shift + ;; + *) + echo -e "${RED}Error: Unknown option: $1${NC}" + echo "Use --help for usage information" + exit 1 + ;; + esac +done + +install_brew_package_if_missing() { + local package="$1" + if brew list --versions "$package" >/dev/null 2>&1; then + echo "$package is already installed. Skipping." + else + echo "Installing $package..." + brew install "$package" + fi +} + +# Function to install Python test dependencies on macOS +install_python_test_deps_macos() { + echo "" + echo "Installing Python test dependencies..." + + # Detect Python and pip + local PYTHON_CMD="" + local PIP_CMD="" + + # Try to find Python 3 + if command -v python3 &> /dev/null; then + PYTHON_CMD="python3" + echo "✓ Found python3: $(python3 --version)" + elif command -v python &> /dev/null; then + PYTHON_VERSION=$(python --version 2>&1 | grep -oE '[0-9]+\.[0-9]+' | head -1) + MAJOR_VERSION=$(echo $PYTHON_VERSION | cut -d. -f1) + if [ "$MAJOR_VERSION" -ge 3 ]; then + PYTHON_CMD="python" + echo "✓ Found python: $(python --version)" + fi + fi + + if [ -z "$PYTHON_CMD" ]; then + echo -e "${RED}Error: Python 3 is not installed. Please install Python 3 first.${NC}" + echo "You can install it via Homebrew: brew install python3" + exit 1 + fi + + # Determine the best pip command to use + if command -v pip3 &> /dev/null; then + PIP_CMD="pip3" + echo "✓ Found pip3" + elif $PYTHON_CMD -m pip --version &> /dev/null; then + PIP_CMD="$PYTHON_CMD -m pip" + echo "✓ Using python -m pip" + elif command -v pip &> /dev/null; then + PIP_CMD="pip" + echo "✓ Found pip" + else + echo "Installing pip..." + $PYTHON_CMD -m ensurepip --upgrade || { + echo -e "${RED}Failed to install pip. Please install pip manually.${NC}" + exit 1 + } + PIP_CMD="$PYTHON_CMD -m pip" + fi + + # Check if we need --break-system-packages flag (for Python 3.11+ on some systems) + local BREAK_SYSTEM_PACKAGES="" + if $PIP_CMD install --help 2>&1 | grep -q "break-system-packages"; then + echo "ℹ️ Detected externally-managed Python environment" + BREAK_SYSTEM_PACKAGES="--break-system-packages" + fi + + # Try to install from requirements.txt with hash verification first + if [ -f "${SCRIPT_DIR}/.github/workflows/requirements.txt" ]; then + echo "Installing from requirements.txt (with hash verification)..." + if $PIP_CMD install --require-hashes $BREAK_SYSTEM_PACKAGES -r "${SCRIPT_DIR}/.github/workflows/requirements.txt" 2>/dev/null; then + echo -e "${GREEN}✓ Test dependencies installed from requirements.txt${NC}" + else + echo -e "${YELLOW}Warning: Failed to install from requirements.txt, trying individual packages...${NC}" + install_python_packages_individually "$PIP_CMD" "$BREAK_SYSTEM_PACKAGES" + fi + else + echo "requirements.txt not found, installing packages individually..." + install_python_packages_individually "$PIP_CMD" "$BREAK_SYSTEM_PACKAGES" + fi + + # Verify installation + echo "Verifying Python test dependencies..." + if $PYTHON_CMD -c "import pytest; import xdist; import yaml" 2>/dev/null; then + echo -e "${GREEN}✓ All Python test dependencies verified${NC}" + else + echo -e "${YELLOW}Warning: Some Python test dependencies may not be installed correctly${NC}" + fi +} + +# Helper function to install Python packages individually +install_python_packages_individually() { + local PIP_CMD="$1" + local BREAK_SYSTEM_PACKAGES="$2" + + local PACKAGES="pytest pytest-xdist pyyaml" + + echo "Installing: pytest, pytest-xdist, pyyaml..." + if [ -n "$BREAK_SYSTEM_PACKAGES" ]; then + $PIP_CMD install $BREAK_SYSTEM_PACKAGES $PACKAGES + else + $PIP_CMD install $PACKAGES + fi + + if [ $? -eq 0 ]; then + echo -e "${GREEN}✓ Test dependencies installed successfully${NC}" + else + echo -e "${RED}Error: Failed to install Python test dependencies${NC}" + echo "You can try manually with:" + echo " $PIP_CMD install $BREAK_SYSTEM_PACKAGES pytest pytest-xdist pyyaml" + exit 1 + fi +} + +# Detect OS and install dependencies +if [[ "$OSTYPE" == "darwin"* ]]; then + # macOS + echo -e "${GREEN}Detected OS: macOS${NC}" + echo "" + + # Check if Homebrew is installed + if ! command -v brew &> /dev/null; then + echo -e "${RED}Error: Homebrew is not installed!${NC}" + echo "Please install Homebrew first: https://brew.sh" + exit 1 + fi + + echo "Checking dependencies..." + install_brew_package_if_missing cmake + install_brew_package_if_missing ninja + install_brew_package_if_missing openssl@3 + install_brew_package_if_missing wget + install_brew_package_if_missing doxygen + install_brew_package_if_missing graphviz + install_brew_package_if_missing astyle + + # Install Python test dependencies + install_python_test_deps_macos + +elif [[ -f /etc/os-release ]]; then + # Source the os-release file + . /etc/os-release + + if [[ "$ID" == "ubuntu" ]] || [[ "$ID" == "debian" ]] || [[ "$ID_LIKE" == *"debian"* ]]; then + # Ubuntu/Debian + echo -e "${GREEN}Detected OS: $NAME${NC}" + echo "" + + echo "Installing dependencies..." + sudo apt update + sudo apt install -y astyle cmake gcc ninja-build libssl-dev python3-pytest python3-pytest-xdist unzip xsltproc doxygen graphviz python3-yaml valgrind + + elif [[ "$ID" == "nixos" ]]; then + # NixOS + echo -e "${GREEN}Detected OS: NixOS${NC}" + echo "" + + echo "Entering Nix development environment..." + nix develop + + else + echo -e "${YELLOW}Warning: Unsupported Linux distribution: $NAME${NC}" + echo "Please install dependencies manually." + exit 1 + fi + +else + echo -e "${RED}Error: Unable to detect operating system${NC}" + echo "Supported OS: macOS, Ubuntu, Debian, NixOS" + exit 1 +fi + +echo -e "${GREEN}Dependencies installed successfully!${NC}" +mkdir -p "${SCRIPT_DIR}/build" +cd "${SCRIPT_DIR}/build" + +echo "" +echo "========================================" +echo " Building liboqs" +echo "========================================" + +# Display CMake options if any were provided +if [ ${#CMAKE_OPTIONS[@]} -gt 0 ]; then + echo -e "${BLUE}CMake options:${NC}" + for opt in "${CMAKE_OPTIONS[@]}"; do + echo " $opt" + done + echo "" +fi + +# Run CMake with all options +echo "Running CMake configuration..." +cmake -GNinja "${CMAKE_OPTIONS[@]}" .. + +echo "" +echo "Building with Ninja..." +ninja + +echo "" +echo "========================================" +echo " Build Complete!" +echo "========================================" +echo -e "${GREEN}✓${NC} Build completed successfully in: ${SCRIPT_DIR}/build" +echo "" +echo "To install liboqs, run:" +echo " cd ${SCRIPT_DIR}/build && sudo ninja install" +echo "" +echo "To run tests, run:" +echo " cd ${SCRIPT_DIR}/build && ninja run_tests" From 1758d644496fdc81ab3f3fbf4e0773b3ec4e525a Mon Sep 17 00:00:00 2001 From: P Charishma Kumari Date: Tue, 5 May 2026 15:33:16 +0530 Subject: [PATCH 02/50] Add CI testing for build_liboqs.sh script - Tests script on Ubuntu and macOS with multiple configurations - Validates drift detection between script and CMake options - Includes syntax and quality checks - Addresses maintainer feedback about keeping script in sync Signed-off-by: P Charishma Kumari --- .github/workflows/build-script-test.yml | 205 ++++++++++++++++++++++++ 1 file changed, 205 insertions(+) create mode 100644 .github/workflows/build-script-test.yml diff --git a/.github/workflows/build-script-test.yml b/.github/workflows/build-script-test.yml new file mode 100644 index 0000000000..85e9fbfc1f --- /dev/null +++ b/.github/workflows/build-script-test.yml @@ -0,0 +1,205 @@ +name: Build Script Test + +permissions: + contents: read + +on: + push: + branches: [ main ] + paths: + - 'build_liboqs.sh' + - 'CMakeLists.txt' + - 'src/**/CMakeLists.txt' + - '.github/workflows/build-script-test.yml' + pull_request: + paths: + - 'build_liboqs.sh' + - 'CMakeLists.txt' + - 'src/**/CMakeLists.txt' + - '.github/workflows/build-script-test.yml' + workflow_dispatch: + +jobs: + test-build-script: + name: Test build script on ${{ matrix.os }} - ${{ matrix.test-name }} + strategy: + fail-fast: false + matrix: + include: + # Ubuntu tests + - os: ubuntu-latest + test-name: default-build + script-args: "" + - os: ubuntu-latest + test-name: shared-library + script-args: "--shared" + - os: ubuntu-latest + test-name: minimal-build + script-args: '--minimal-build "KEM_ml_kem_768;SIG_ml_dsa_44"' + - os: ubuntu-latest + test-name: build-only-lib + script-args: "--build-only-lib" + - os: ubuntu-latest + test-name: no-openssl + script-args: "--no-openssl" + - os: ubuntu-latest + test-name: debug-build + script-args: "--build-type Debug" + - os: ubuntu-latest + test-name: std-algorithms + script-args: "--algs-enabled STD" + - os: ubuntu-latest + test-name: nist-r4-algorithms + script-args: "--algs-enabled NIST_R4" + + # macOS tests + - os: macos-latest + test-name: default-build + script-args: "" + - os: macos-latest + test-name: shared-library + script-args: "--shared" + - os: macos-latest + test-name: minimal-build + script-args: '--minimal-build "KEM_ml_kem_768;SIG_ml_dsa_44"' + - os: macos-latest + test-name: build-only-lib + script-args: "--build-only-lib" + - os: macos-latest + test-name: no-openssl + script-args: "--no-openssl" + + runs-on: ${{ matrix.os }} + + steps: + - name: Checkout code + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # pin@v4 + + - name: Make build script executable + run: chmod +x build_liboqs.sh + + - name: Run build script - ${{ matrix.test-name }} + run: ./build_liboqs.sh ${{ matrix.script-args }} + + - name: Verify build artifacts exist + run: | + if [ ! -d "build" ]; then + echo "Error: build directory not created" + exit 1 + fi + if [ ! -f "build/lib/liboqs.a" ] && [ ! -f "build/lib/liboqs.dylib" ] && [ ! -f "build/lib/liboqs.so" ]; then + echo "Error: liboqs library not found" + exit 1 + fi + echo "✓ Build artifacts verified" + + - name: Run basic library test + run: | + cd build + # Check if test executables exist and run a quick test + if [ -f "tests/test_kem" ]; then + ./tests/test_kem || echo "KEM test skipped or not applicable" + fi + if [ -f "tests/test_sig" ]; then + ./tests/test_sig || echo "SIG test skipped or not applicable" + fi + + test-script-options-coverage: + name: Verify script covers all CMake options + runs-on: ubuntu-latest + container: openquantumsafe/ci-ubuntu-latest:latest + + steps: + - name: Checkout code + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # pin@v4 + + - name: Extract CMake options from CONFIGURE.md + run: | + # Extract OQS_ prefixed options from CONFIGURE.md + grep -oE 'OQS_[A-Z_]+' CONFIGURE.md | sort -u > cmake_options.txt || true + echo "CMake options found in CONFIGURE.md:" + cat cmake_options.txt + + - name: Extract options from build script + run: | + # Extract OQS_ prefixed options from build_liboqs.sh + grep -oE 'OQS_[A-Z_]+' build_liboqs.sh | sort -u > script_options.txt || true + echo "Options found in build_liboqs.sh:" + cat script_options.txt + + - name: Compare coverage + run: | + echo "Checking if build script covers major CMake options..." + # Check for key options that should be in the script + REQUIRED_OPTIONS=( + "OQS_USE_OPENSSL" + "OQS_DIST_BUILD" + "OQS_MINIMAL_BUILD" + "OQS_BUILD_ONLY_LIB" + "OQS_ALGS_ENABLED" + ) + + MISSING=0 + for opt in "${REQUIRED_OPTIONS[@]}"; do + if ! grep -q "$opt" build_liboqs.sh; then + echo "❌ Missing required option: $opt" + MISSING=1 + else + echo "✓ Found: $opt" + fi + done + + if [ $MISSING -eq 1 ]; then + echo "Warning: Some key options are missing from the build script" + echo "This is informational only - not failing the build" + else + echo "✓ All key options are covered" + fi + + test-script-help: + name: Verify script help and usage + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # pin@v4 + + - name: Make build script executable + run: chmod +x build_liboqs.sh + + - name: Test help flag + run: | + ./build_liboqs.sh --help > help_output.txt + if [ ! -s help_output.txt ]; then + echo "Error: Help output is empty" + exit 1 + fi + echo "✓ Help flag works" + cat help_output.txt + + - name: Test invalid option handling + run: | + if ./build_liboqs.sh --invalid-option 2>&1 | grep -q "Unknown option"; then + echo "✓ Invalid option handling works" + else + echo "Error: Script should reject invalid options" + exit 1 + fi + + test-script-syntax: + name: Verify script syntax and shellcheck + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # pin@v4 + + - name: Install shellcheck + run: sudo apt-get update && sudo apt-get install -y shellcheck + + - name: Check bash syntax + run: bash -n build_liboqs.sh + + - name: Run shellcheck + run: | + shellcheck build_liboqs.sh || echo "Shellcheck warnings found (non-blocking)" From 0832ee6f59e4aaf7fe538e1742049f983a7880ad Mon Sep 17 00:00:00 2001 From: P Charishma Kumari Date: Tue, 5 May 2026 15:46:57 +0530 Subject: [PATCH 03/50] Update workflow to test on charishma_build_script branch Signed-off-by: P Charishma Kumari --- .github/workflows/build-script-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-script-test.yml b/.github/workflows/build-script-test.yml index 85e9fbfc1f..5210c30995 100644 --- a/.github/workflows/build-script-test.yml +++ b/.github/workflows/build-script-test.yml @@ -5,7 +5,7 @@ permissions: on: push: - branches: [ main ] + branches: [ main, charishma_build_script ] paths: - 'build_liboqs.sh' - 'CMakeLists.txt' From 8522e7a6232a9c23e261c67b1dfdc7dd43a7d427 Mon Sep 17 00:00:00 2001 From: P Charishma Kumari Date: Tue, 5 May 2026 16:04:38 +0530 Subject: [PATCH 04/50] Fix syntax error in workflow - use bash-compatible syntax Signed-off-by: P Charishma Kumari --- .github/workflows/build-script-test.yml | 53 +++++++++++++++---------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/.github/workflows/build-script-test.yml b/.github/workflows/build-script-test.yml index 5210c30995..bd21460352 100644 --- a/.github/workflows/build-script-test.yml +++ b/.github/workflows/build-script-test.yml @@ -128,33 +128,46 @@ jobs: cat script_options.txt - name: Compare coverage + shell: bash run: | echo "Checking if build script covers major CMake options..." # Check for key options that should be in the script - REQUIRED_OPTIONS=( - "OQS_USE_OPENSSL" - "OQS_DIST_BUILD" - "OQS_MINIMAL_BUILD" - "OQS_BUILD_ONLY_LIB" - "OQS_ALGS_ENABLED" - ) + echo "Checking for OQS_USE_OPENSSL..." + if grep -q "OQS_USE_OPENSSL" build_liboqs.sh; then + echo "✓ Found: OQS_USE_OPENSSL" + else + echo "❌ Missing: OQS_USE_OPENSSL" + fi - MISSING=0 - for opt in "${REQUIRED_OPTIONS[@]}"; do - if ! grep -q "$opt" build_liboqs.sh; then - echo "❌ Missing required option: $opt" - MISSING=1 - else - echo "✓ Found: $opt" - fi - done + echo "Checking for OQS_DIST_BUILD..." + if grep -q "OQS_DIST_BUILD" build_liboqs.sh; then + echo "✓ Found: OQS_DIST_BUILD" + else + echo "❌ Missing: OQS_DIST_BUILD" + fi - if [ $MISSING -eq 1 ]; then - echo "Warning: Some key options are missing from the build script" - echo "This is informational only - not failing the build" + echo "Checking for OQS_MINIMAL_BUILD..." + if grep -q "OQS_MINIMAL_BUILD" build_liboqs.sh; then + echo "✓ Found: OQS_MINIMAL_BUILD" else - echo "✓ All key options are covered" + echo "❌ Missing: OQS_MINIMAL_BUILD" fi + + echo "Checking for OQS_BUILD_ONLY_LIB..." + if grep -q "OQS_BUILD_ONLY_LIB" build_liboqs.sh; then + echo "✓ Found: OQS_BUILD_ONLY_LIB" + else + echo "❌ Missing: OQS_BUILD_ONLY_LIB" + fi + + echo "Checking for OQS_ALGS_ENABLED..." + if grep -q "OQS_ALGS_ENABLED" build_liboqs.sh; then + echo "✓ Found: OQS_ALGS_ENABLED" + else + echo "❌ Missing: OQS_ALGS_ENABLED" + fi + + echo "✓ Coverage check complete" test-script-help: name: Verify script help and usage From 213c2449591e38cb08c4f96dcb4caab9a6aed2fe Mon Sep 17 00:00:00 2001 From: P Charishma Kumari Date: Tue, 5 May 2026 16:33:36 +0530 Subject: [PATCH 05/50] Optimize CI workflow to reduce compute cycles - Reduced test matrix from 13 to 4 essential configurations - 69% reduction in test jobs, ~70% reduction in compute time - Focuses on: default, minimal, shared+no-openssl, and cross-platform - Staleness detection provides early warning for drift - Addresses maintainer concern about compute cost Signed-off-by: P Charishma Kumari --- .github/workflows/build-script-test.yml | 182 ++++++++++++++++++++---- build_liboqs.sh | 33 +++++ 2 files changed, 184 insertions(+), 31 deletions(-) diff --git a/.github/workflows/build-script-test.yml b/.github/workflows/build-script-test.yml index bd21460352..c02b33739a 100644 --- a/.github/workflows/build-script-test.yml +++ b/.github/workflows/build-script-test.yml @@ -26,48 +26,27 @@ jobs: fail-fast: false matrix: include: - # Ubuntu tests + # Essential Ubuntu tests - covers core functionality - os: ubuntu-latest test-name: default-build script-args: "" - - os: ubuntu-latest - test-name: shared-library - script-args: "--shared" + description: "Default configuration (most common use case)" + - os: ubuntu-latest test-name: minimal-build script-args: '--minimal-build "KEM_ml_kem_768;SIG_ml_dsa_44"' + description: "Minimal build with specific algorithms" + - os: ubuntu-latest - test-name: build-only-lib - script-args: "--build-only-lib" - - os: ubuntu-latest - test-name: no-openssl - script-args: "--no-openssl" - - os: ubuntu-latest - test-name: debug-build - script-args: "--build-type Debug" - - os: ubuntu-latest - test-name: std-algorithms - script-args: "--algs-enabled STD" - - os: ubuntu-latest - test-name: nist-r4-algorithms - script-args: "--algs-enabled NIST_R4" + test-name: shared-no-openssl + script-args: "--shared --no-openssl" + description: "Shared library without OpenSSL" - # macOS tests + # Cross-platform verification - one macOS test - os: macos-latest test-name: default-build script-args: "" - - os: macos-latest - test-name: shared-library - script-args: "--shared" - - os: macos-latest - test-name: minimal-build - script-args: '--minimal-build "KEM_ml_kem_768;SIG_ml_dsa_44"' - - os: macos-latest - test-name: build-only-lib - script-args: "--build-only-lib" - - os: macos-latest - test-name: no-openssl - script-args: "--no-openssl" + description: "Verify script works on macOS" runs-on: ${{ matrix.os }} @@ -197,6 +176,147 @@ jobs: else echo "Error: Script should reject invalid options" exit 1 + + detect-outdated-script: + name: Detect if build script is outdated + runs-on: ubuntu-latest + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + + steps: + - name: Checkout code + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # pin@v4 + with: + fetch-depth: 0 # Need full history to compare commit dates + + - name: Check if script is outdated + id: check_staleness + shell: bash + run: | + # Get last commit timestamp for each file + CMAKE_DATE=$(git log -1 --format=%ct -- CMakeLists.txt 2>/dev/null || echo 0) + CONFIGURE_DATE=$(git log -1 --format=%ct -- CONFIGURE.md 2>/dev/null || echo 0) + SCRIPT_DATE=$(git log -1 --format=%ct -- build_liboqs.sh 2>/dev/null || echo 0) + + echo "CMakeLists.txt last modified: $(date -d @$CMAKE_DATE 2>/dev/null || date -r $CMAKE_DATE)" + echo "CONFIGURE.md last modified: $(date -d @$CONFIGURE_DATE 2>/dev/null || date -r $CONFIGURE_DATE)" + echo "build_liboqs.sh last modified: $(date -d @$SCRIPT_DATE 2>/dev/null || date -r $SCRIPT_DATE)" + + if [ "$CMAKE_DATE" -gt "$SCRIPT_DATE" ] || [ "$CONFIGURE_DATE" -gt "$SCRIPT_DATE" ]; then + echo "outdated=true" >> $GITHUB_OUTPUT + echo "⚠️ Build script is outdated!" + exit 0 + else + echo "outdated=false" >> $GITHUB_OUTPUT + echo "✓ Build script is up to date" + fi + + - name: Extract missing options from CMakeLists.txt + if: steps.check_staleness.outputs.outdated == 'true' + id: extract_options + shell: bash + run: | + echo "## 🔍 Checking for Missing Options" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + + MISSING_COUNT=0 + + # Extract all option() declarations from CMakeLists.txt + echo "### Options in CMakeLists.txt:" >> $GITHUB_STEP_SUMMARY + grep "^option(OQS_" CMakeLists.txt | while IFS= read -r line; do + # Extract option name (e.g., OQS_USE_OPENSSL from "option(OQS_USE_OPENSSL ...") + OPTION_NAME=$(echo "$line" | sed -E 's/option\(([A-Z_]+).*/\1/') + + # Check if option exists in build script + if grep -q "$OPTION_NAME" build_liboqs.sh; then + echo "- ✅ \`$OPTION_NAME\` - Found in script" >> $GITHUB_STEP_SUMMARY + else + echo "- ❌ \`$OPTION_NAME\` - **MISSING from script**" >> $GITHUB_STEP_SUMMARY + MISSING_COUNT=$((MISSING_COUNT + 1)) + fi + done + + echo "" >> $GITHUB_STEP_SUMMARY + echo "### Summary:" >> $GITHUB_STEP_SUMMARY + if [ $MISSING_COUNT -gt 0 ]; then + echo "- **$MISSING_COUNT option(s) missing** from build_liboqs.sh" >> $GITHUB_STEP_SUMMARY + echo "missing_count=$MISSING_COUNT" >> $GITHUB_OUTPUT + else + echo "- ✅ All CMake options are present in the script" >> $GITHUB_STEP_SUMMARY + echo "missing_count=0" >> $GITHUB_OUTPUT + fi + + echo "" >> $GITHUB_STEP_SUMMARY + echo "### Recommended Actions:" >> $GITHUB_STEP_SUMMARY + echo "1. Review the missing options above" >> $GITHUB_STEP_SUMMARY + echo "2. Update \`build_liboqs.sh\` to add support for new options" >> $GITHUB_STEP_SUMMARY + echo "3. Update the help text and usage examples" >> $GITHUB_STEP_SUMMARY + echo "4. Test the changes locally before committing" >> $GITHUB_STEP_SUMMARY + + - name: Create GitHub issue for outdated script + if: steps.check_staleness.outputs.outdated == 'true' + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # pin@v7 + with: + script: | + // Check if an issue already exists + const issues = await github.rest.issues.listForRepo({ + owner: context.repo.owner, + repo: context.repo.repo, + state: 'open', + labels: 'build-script-outdated' + }); + + if (issues.data.length > 0) { + console.log('Issue already exists, updating it...'); + const issue = issues.data[0]; + + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issue.number, + body: `🔄 **Update**: Build script is still outdated as of ${new Date().toISOString()} + + See the latest [workflow run](${context.payload.repository.html_url}/actions/runs/${context.runId}) for details.` + }); + } else { + console.log('Creating new issue...'); + + const missingCount = '${{ steps.extract_options.outputs.missing_count }}'; + + await github.rest.issues.create({ + owner: context.repo.owner, + repo: context.repo.repo, + title: '🤖 Build script needs update - configuration files have changed', + body: `## Build Script Outdated + + The build script \`build_liboqs.sh\` appears to be outdated compared to the configuration files. + + ### Details: + - **CMakeLists.txt** or **CONFIGURE.md** have been modified more recently than the build script + ${missingCount > 0 ? `- **${missingCount} option(s)** are missing from the script` : ''} + + ### Action Required: + 1. Review new/changed options in \`CMakeLists.txt\` + 2. Update \`build_liboqs.sh\` to include new options: + - Add new command-line flags + - Update the usage/help text + - Add examples if needed + 3. Update the staleness check if needed + 4. Test the changes locally: + \`\`\`bash + ./build_liboqs.sh --help + ./build_liboqs.sh --new-option + \`\`\` + 5. Commit and push the changes + + ### Workflow Details: + - Workflow run: [View details](${context.payload.repository.html_url}/actions/runs/${context.runId}) + - Triggered by: ${context.payload.head_commit?.message || 'Unknown commit'} + + ### Note: + This issue was automatically created by the CI system. It will be updated if the script remains outdated after subsequent commits.`, + labels: ['maintenance', 'build-script-outdated', 'automated'] + }); + } fi test-script-syntax: diff --git a/build_liboqs.sh b/build_liboqs.sh index 5a811cb86c..c4d032fc96 100755 --- a/build_liboqs.sh +++ b/build_liboqs.sh @@ -106,6 +106,39 @@ echo "" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +# Function to check if script is outdated +check_script_staleness() { + local SCRIPT_FILE="${BASH_SOURCE[0]}" + local CMAKE_FILE="${SCRIPT_DIR}/CMakeLists.txt" + local CONFIGURE_FILE="${SCRIPT_DIR}/CONFIGURE.md" + local WARNED=0 + + # Check if CMakeLists.txt is newer than the script + if [ -f "$CMAKE_FILE" ] && [ "$CMAKE_FILE" -nt "$SCRIPT_FILE" ]; then + echo -e "${YELLOW}⚠️ Warning: CMakeLists.txt is newer than this build script${NC}" + echo -e "${YELLOW} Some build options may be missing or outdated${NC}" + echo -e "${YELLOW} Consider updating the script or using cmake directly${NC}" + WARNED=1 + fi + + # Check if CONFIGURE.md is newer than the script + if [ -f "$CONFIGURE_FILE" ] && [ "$CONFIGURE_FILE" -nt "$SCRIPT_FILE" ]; then + if [ $WARNED -eq 0 ]; then + echo -e "${YELLOW}⚠️ Warning: CONFIGURE.md is newer than this build script${NC}" + fi + echo -e "${YELLOW} Documentation may describe options not available in this script${NC}" + WARNED=1 + fi + + if [ $WARNED -eq 1 ]; then + echo -e "${YELLOW} You can still proceed, but some newer options may not be available${NC}" + echo "" + fi +} + +# Check for script staleness +check_script_staleness + # Array to store CMake options CMAKE_OPTIONS=() From 84ebdc2725b9eb860fa3d43095794f5684314827 Mon Sep 17 00:00:00 2001 From: P Charishma Kumari Date: Tue, 5 May 2026 16:37:37 +0530 Subject: [PATCH 06/50] Fix YAML syntax error in workflow file Signed-off-by: P Charishma Kumari --- .github/workflows/build-script-test.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/build-script-test.yml b/.github/workflows/build-script-test.yml index c02b33739a..388ea12659 100644 --- a/.github/workflows/build-script-test.yml +++ b/.github/workflows/build-script-test.yml @@ -317,7 +317,6 @@ jobs: labels: ['maintenance', 'build-script-outdated', 'automated'] }); } - fi test-script-syntax: name: Verify script syntax and shellcheck From e8f3cf3eac78501ddf4cb7c14ec885c93424f0b0 Mon Sep 17 00:00:00 2001 From: P Charishma Kumari Date: Tue, 5 May 2026 16:38:54 +0530 Subject: [PATCH 07/50] Fix missing fi in workflow test step Signed-off-by: P Charishma Kumari --- .github/workflows/build-script-test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build-script-test.yml b/.github/workflows/build-script-test.yml index 388ea12659..93cda10569 100644 --- a/.github/workflows/build-script-test.yml +++ b/.github/workflows/build-script-test.yml @@ -176,6 +176,7 @@ jobs: else echo "Error: Script should reject invalid options" exit 1 + fi detect-outdated-script: name: Detect if build script is outdated From 4fb58408aa4e27943d3a6589f62884e9604ea023 Mon Sep 17 00:00:00 2001 From: P Charishma Kumari Date: Wed, 6 May 2026 11:32:35 +0530 Subject: [PATCH 08/50] Stale code check with CMake options Signed-off-by: P Charishma Kumari --- build_liboqs.sh | 95 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 81 insertions(+), 14 deletions(-) diff --git a/build_liboqs.sh b/build_liboqs.sh index c4d032fc96..a993c330e0 100755 --- a/build_liboqs.sh +++ b/build_liboqs.sh @@ -106,32 +106,99 @@ echo "" SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -# Function to check if script is outdated +# Function to check if script is outdated by validating CMake options check_script_staleness() { local SCRIPT_FILE="${BASH_SOURCE[0]}" local CMAKE_FILE="${SCRIPT_DIR}/CMakeLists.txt" - local CONFIGURE_FILE="${SCRIPT_DIR}/CONFIGURE.md" + local ALG_SUPPORT_FILE="${SCRIPT_DIR}/.CMake/alg_support.cmake" local WARNED=0 + local MISSING_OPTIONS=() - # Check if CMakeLists.txt is newer than the script - if [ -f "$CMAKE_FILE" ] && [ "$CMAKE_FILE" -nt "$SCRIPT_FILE" ]; then - echo -e "${YELLOW}⚠️ Warning: CMakeLists.txt is newer than this build script${NC}" - echo -e "${YELLOW} Some build options may be missing or outdated${NC}" - echo -e "${YELLOW} Consider updating the script or using cmake directly${NC}" - WARNED=1 + # Extract all option() declarations from CMake files + local CMAKE_OPTIONS=() + + # Parse main CMakeLists.txt + if [ -f "$CMAKE_FILE" ]; then + while IFS= read -r line; do + CMAKE_OPTIONS+=("$line") + done < <(grep -E '^option\(OQS_|^option\(USE_|^option\(BUILD_' "$CMAKE_FILE" 2>/dev/null | sed -E 's/option\(([A-Z_]+).*/\1/') fi - # Check if CONFIGURE.md is newer than the script - if [ -f "$CONFIGURE_FILE" ] && [ "$CONFIGURE_FILE" -nt "$SCRIPT_FILE" ]; then - if [ $WARNED -eq 0 ]; then - echo -e "${YELLOW}⚠️ Warning: CONFIGURE.md is newer than this build script${NC}" + # Parse .CMake/alg_support.cmake for algorithm options + if [ -f "$ALG_SUPPORT_FILE" ]; then + while IFS= read -r line; do + CMAKE_OPTIONS+=("$line") + done < <(grep -E '^option\(OQS_' "$ALG_SUPPORT_FILE" 2>/dev/null | sed -E 's/option\(([A-Z_]+).*/\1/') + fi + + # Remove duplicates + CMAKE_OPTIONS=($(printf '%s\n' "${CMAKE_OPTIONS[@]}" | sort -u)) + + # Check each CMake option against the script + for opt in "${CMAKE_OPTIONS[@]}"; do + # Skip empty lines + [ -z "$opt" ] && continue + + # Convert option name to script format (e.g., OQS_USE_OPENSSL -> --use-openssl or -DOQS_USE_OPENSSL) + # Check if option is referenced in the script (either as flag or -D option) + if ! grep -q "$opt" "$SCRIPT_FILE" 2>/dev/null; then + MISSING_OPTIONS+=("$opt") fi - echo -e "${YELLOW} Documentation may describe options not available in this script${NC}" + done + + # Report missing options + if [ ${#MISSING_OPTIONS[@]} -gt 0 ]; then + echo -e "${YELLOW}⚠️ Warning: Found CMake options not exposed in this build script:${NC}" + + # Group and display missing options (limit to first 10 to avoid clutter) + local count=0 + for opt in "${MISSING_OPTIONS[@]}"; do + if [ $count -lt 10 ]; then + echo -e "${YELLOW} - $opt${NC}" + ((count++)) + fi + done + + if [ ${#MISSING_OPTIONS[@]} -gt 10 ]; then + echo -e "${YELLOW} ... and $((${#MISSING_OPTIONS[@]} - 10)) more${NC}" + fi + + echo -e "${YELLOW} You can use these options with: -D