#!/usr/bin/env bash # # Build a tiny project for every curated-linkdb package, compile against the # library, and verify the binary links. Catches nixpkgs attribute drift, # find_package case mismatches, and missing components configurations. # # Usage: # scripts/verify-curated-db.sh [pkg1 pkg2 ...] # # Env: # CARGOXX absolute path to the cargoxx binary (default: ./build/cargoxx) # VERIFY_DIR working directory (default: a fresh mktemp under /tmp) # KEEP non-empty → leave VERIFY_DIR in place after the run # # Catch2 and gtest are intentionally skipped: their default linkdb targets # (Catch2WithMain, GTest::gtest_main) supply their own main() and would # collide with the using-snippet's int main(). set -uo pipefail REPO_ROOT="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)" CARGOXX="${CARGOXX:-${REPO_ROOT}/build/cargoxx}" SNIPPETS_DIR="${REPO_ROOT}/scripts/curated-snippets" if [[ ! -x "${CARGOXX}" ]]; then echo "ERROR: cargoxx binary not found at ${CARGOXX}" >&2 echo " build it first: cmake --build build" >&2 exit 2 fi if [[ -z "${VERIFY_DIR:-}" ]]; then VERIFY_DIR="$(mktemp -d -t cargoxx-verify-XXXXXX)" fi mkdir -p "${VERIFY_DIR}" if [[ -z "${KEEP:-}" ]]; then trap 'rm -rf "${VERIFY_DIR}"' EXIT fi echo "cargoxx: ${CARGOXX}" echo "verify dir: ${VERIFY_DIR}" echo # Format: "name|version|components" (components is comma-separated, may be empty) ALL_PACKAGES=( "fmt|10.2.0|" "spdlog|1.13.0|" "nlohmann_json|3.11.0|" "boost|1.84.0|" "openssl|3.2.0|" "zlib|1.3.0|" "sqlite3|3.45.0|" "curl|8.5.0|" "protobuf|25.0.0|" "eigen|3.4.0|" "tbb|2021.10.0|" "libpng|1.6.40|" "libjpeg|3.0.1|" "freetype|2.13.2|" "glfw|3.3.9|" "glm|0.9.9.8|" "sdl2|2.28.5|" "cli11|2.4.1|" "cxxopts|3.2.0|" "range-v3|0.12.0|" "magic_enum|0.9.5|" ) SKIPPED_PACKAGES=( "catch2 (links Catch2WithMain — conflicts with the snippet's main())" "gtest (links GTest::gtest_main — conflicts with the snippet's main())" "grpc (find_dependency(Protobuf) transitive — needs cross-package deps)" "abseil-cpp (nixpkgs builds it against libstdc++; our flake uses libc++)" ) # Allow running on a subset: ./scripts/verify-curated-db.sh fmt boost FILTER=("$@") is_filtered() { local name="$1" if [[ ${#FILTER[@]} -eq 0 ]]; then return 0 fi local f for f in "${FILTER[@]}"; do if [[ "${f}" == "${name}" ]]; then return 0 fi done return 1 } ok=() failed=() run_one() { local name="$1" version="$2" components="$3" local snippet="${SNIPPETS_DIR}/${name}.cpp" if [[ ! -f "${snippet}" ]]; then echo " ✗ no snippet at ${snippet}" >&2 failed+=("${name}: missing snippet") return 1 fi local proj="${VERIFY_DIR}/${name}" rm -rf "${proj}" pushd "${VERIFY_DIR}" >/dev/null || return 1 if ! "${CARGOXX}" new "${name}" >"${VERIFY_DIR}/${name}.new.log" 2>&1; then echo " ✗ cargoxx new failed (log: ${VERIFY_DIR}/${name}.new.log)" >&2 failed+=("${name}: cargoxx new") popd >/dev/null return 1 fi popd >/dev/null pushd "${proj}" >/dev/null || return 1 local add_args=("${name}@${version}") if [[ -n "${components}" ]]; then add_args+=("--components" "${components}") fi if ! "${CARGOXX}" add "${add_args[@]}" >"${VERIFY_DIR}/${name}.add.log" 2>&1; then echo " ✗ cargoxx add failed (log: ${VERIFY_DIR}/${name}.add.log)" >&2 failed+=("${name}: cargoxx add") popd >/dev/null return 1 fi cp "${snippet}" src/main.cpp if ! "${CARGOXX}" build >"${VERIFY_DIR}/${name}.build.log" 2>&1; then echo " ✗ cargoxx build failed (log: ${VERIFY_DIR}/${name}.build.log)" >&2 failed+=("${name}: cargoxx build") popd >/dev/null return 1 fi if [[ ! -x "build/debug/${name}" ]]; then echo " ✗ binary not produced at build/debug/${name}" >&2 failed+=("${name}: missing binary") popd >/dev/null return 1 fi popd >/dev/null ok+=("${name}") echo " ✓ ${name}" return 0 } for entry in "${ALL_PACKAGES[@]}"; do IFS='|' read -r name version components <<<"${entry}" if ! is_filtered "${name}"; then continue fi echo "=== ${name} ${version} ===" run_one "${name}" "${version}" "${components}" done echo echo "=============================" echo "RESULTS" echo "=============================" echo "OK: ${#ok[@]}" for n in "${ok[@]}"; do echo " ✓ ${n}"; done echo if [[ ${#failed[@]} -gt 0 ]]; then echo "FAILED: ${#failed[@]}" for f in "${failed[@]}"; do echo " ✗ ${f}"; done fi echo echo "SKIPPED: ${#SKIPPED_PACKAGES[@]} (test-framework targets supply own main)" for s in "${SKIPPED_PACKAGES[@]}"; do echo " · ${s}"; done if [[ ${#failed[@]} -gt 0 ]]; then exit 1 fi exit 0