1#!/usr/bin/env bash 2# Write .buckconfig.local: the paths buck2 needs and cannot find itself, because the prelude's C shim 3# execs its tools by absolute path and never searches PATH. 4# 5# tools/configure.sh 6# 7# It reads the tools from PATH (`clang`, `ar`, `python3`, `rustc`) and each Postgres major's install 8# prefix from POSTJEVSQL_PG_<major> (for example POSTJEVSQL_PG_17=/usr/lib/postgresql/17: a directory 9# holding bin/postgres, bin/initdb and bin/pg_config). `mise run configure` sets them. Override any 10# tool with CLANG, CLANGXX, AR, PYTHON; the majors are PG_MAJORS in build/defs.bzl. The file is 11# rewritten only when its content changes, and by rename: buck2 logs any write as a changed file and 12# would read a half-written one as a changed config. 13set -euo pipefail 14cd "$(dirname "$0")/.." 15 16need() { command -v "$1" >/dev/null 2>&1 || { echo "configure: $1 is not on PATH (mise run configure, or mise install)" >&2; exit 1; }; } 17abs() { realpath "$(command -v "$1")"; } 18cc="${CLANG:-$(command -v clang || true)}" 19bindir="$([ -z "$cc" ] || dirname "$cc")" 20# mise exposes a conda tool through small wrapper scripts in <prefix>/.mise-bins; the programs are in <prefix>/bin. 21case "$bindir" in */.mise-bins) bindir="$(dirname "$bindir")/bin" ;; esac 22# conda-forge's clang ships the C++ driver only under its versioned name (clang++-23), which is still the C++ 23# driver, and its own `ar` beside it; mise exposes just `clang` on PATH, so look in the real directory. 24cxx="${CLANGXX:-}" 25if [ -z "$cxx" ] && [ -n "$bindir" ]; then 26 cxx="$(ls "$bindir"/clang++ "$bindir"/clang++-[0-9]* 2>/dev/null | head -1 || true)" 27fi 28[ -n "$cxx" ] || cxx="$(command -v clang++ || true)" 29ar="${AR:-}" 30if [ -z "$ar" ] && [ -n "$bindir" ] && [ -x "$bindir/ar" ]; then ar="$bindir/ar"; fi 31[ -n "$ar" ] || ar="$(command -v ar || true)" 32python="${PYTHON:-$(command -v python3 || true)}" 33for pair in "clang:$cc" "clang++:$cxx" "ar:$ar" "python3:$python"; do 34 [ -n "${pair#*:}" ] || { echo "configure: no ${pair%%:*} found (set ${pair%%:*} on PATH, or see the override variables in this script's header)" >&2; exit 1; } 35done 36need rustc 37 38# The compiler's identity keys buck's cache by compiler (toolchains/BUCK): release and commit. 39identity="rustc-$(rustc -vV | sed -n 's/^release: //p')-$(rustc -vV | sed -n 's/^commit-hash: //p' | cut -c1-12)" 40 41majors=$(sed -n 's/^PG_MAJORS = \[\(.*\)\].*/\1/p' build/defs.bzl | tr -d '" ' | tr ',' ' ') 42[ -n "$majors" ] || { echo "configure: build/defs.bzl has no PG_MAJORS list" >&2; exit 1; } 43per_major="" 44newest="" 45for m in $majors; do 46 var="POSTJEVSQL_PG_$m" 47 prefix="${!var:-}" 48 [ -n "$prefix" ] && [ -x "$prefix/bin/postgres" ] && [ -x "$prefix/bin/pg_config" ] || { 49 echo "configure: $var must name a PostgreSQL $m install (a directory with bin/postgres and bin/pg_config)" >&2; exit 1; } 50 per_major="$per_major 51postgres_bin_$m = $prefix/bin 52pg_config_$m = $prefix/bin/pg_config" 53 newest="$prefix/bin" 54done 55 56tmp=".buckconfig.local.tmp" 57cat > "$tmp" <<CFG 58[toolchain] 59cc = $cc 60cxx = $cxx 61ar = $ar 62python = $python 63[rust] 64rustc_identity = $identity 65[postjevsql] 66postgres_bin = $newest$per_major 67CFG 68if cmp -s "$tmp" .buckconfig.local 2>/dev/null; then rm "$tmp"; else mv "$tmp" .buckconfig.local; fi