180 lines
4.9 KiB
Bash
Executable File
180 lines
4.9 KiB
Bash
Executable File
#!/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
|