From fd70c3b5953f2018c9fbd8dbdbef5c3643cbc071 Mon Sep 17 00:00:00 2001 From: sami Date: Wed, 9 Sep 2026 19:10:40 +0400 Subject: [PATCH] pkg: add tools/bootstrap.sh Installs the full apt dependency set for a clean Ubuntu 26.04 machine (build toolchain, Qt 6, libcurl/sqlite/openssl/secret, ffmpeg, node, lint tools), then verifies versions: cmake >= 3.28, g++ with working -std=c++23 , node >= 20, and every -dev package via pkg-config. --with-clang adds LLVM for the M7 fuzz targets; --packaging adds .deb tooling; --check verifies without installing. Flags the CMake 4.x pre-3.5 cmake_minimum_required hazard from the brief. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01HPPSGhiArbvQgwC2DNiURS --- tools/bootstrap.sh | 208 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 208 insertions(+) create mode 100755 tools/bootstrap.sh diff --git a/tools/bootstrap.sh b/tools/bootstrap.sh new file mode 100755 index 0000000..2bd5f67 --- /dev/null +++ b/tools/bootstrap.sh @@ -0,0 +1,208 @@ +#!/usr/bin/env bash +# +# tools/bootstrap.sh — install every build/test dependency for Velox Download Manager. +# +# Target: a clean Ubuntu 26.04 LTS machine. Safe to re-run (apt is idempotent). +# Owned by lane PKG/QA. Keep this in sync with the table in README.md "Toolchain bootstrap". +# +# ./tools/bootstrap.sh # everything needed to build + test +# ./tools/bootstrap.sh --with-clang # also install clang/LLVM for the libFuzzer targets +# ./tools/bootstrap.sh --packaging # also install .deb tooling (lane PKG, M6) +# ./tools/bootstrap.sh --check # verify versions only, install nothing + +set -euo pipefail + +WITH_CLANG=0 +WITH_PACKAGING=0 +CHECK_ONLY=0 +for arg in "$@"; do + case "$arg" in + --with-clang) WITH_CLANG=1 ;; + --packaging) WITH_PACKAGING=1 ;; + --check) CHECK_ONLY=1 ;; + -h|--help) + sed -n '3,12p' "$0" | sed 's/^# \{0,1\}//' + exit 0 ;; + *) echo "bootstrap: unknown option '$arg'" >&2; exit 2 ;; + esac +done + +log() { printf '\033[1;34m==>\033[0m %s\n' "$*"; } +warn() { printf '\033[1;33mwarning:\033[0m %s\n' "$*" >&2; } +die() { printf '\033[1;31merror:\033[0m %s\n' "$*" >&2; exit 1; } + +# --- sanity -------------------------------------------------------------------- + +[[ "$(uname -s)" == "Linux" ]] || die "this project targets Linux (Ubuntu 26.04)." + +if [[ -r /etc/os-release ]]; then + . /etc/os-release + if [[ "${ID:-}" != "ubuntu" ]]; then + warn "distro is '${ID:-unknown}', not ubuntu — package names may differ." + elif [[ "${VERSION_ID:-}" != "26.04" ]]; then + warn "Ubuntu ${VERSION_ID:-?} detected; the project is developed against 26.04." + fi +fi + +command -v apt-get >/dev/null 2>&1 || die "apt-get not found; install deps manually (see README)." + +SUDO="" +if [[ $EUID -ne 0 ]]; then + command -v sudo >/dev/null 2>&1 || die "not root and no sudo; re-run as root." + SUDO="sudo" +fi + +# --- package sets ----------------------------------------------------------------- +# Full list, so a clean machine gets everything even though the dev box already has most. + +APT_CORE=( + build-essential # g++, make + g++ # C++23 front end (need >= 13; 26.04 ships 15) + gdb + cmake # >= 3.28 (26.04 ships 4.2) + ninja-build + pkg-config + git + python3 # testserver, conformance helpers, codegen + ca-certificates + curl +) + +APT_LIBS=( + libcurl4-openssl-dev # CORE: HTTP stack + libsqlite3-dev # DAEMON: task store + nlohmann-json3-dev # DAEMON/PROTO: JSON-RPC (never in core/) + libssl-dev # CORE: SHA-256 / TLS bits + libsecret-1-dev # DAEMON: Secret Service for credentials + libavformat-dev # MEDIA (M4): HLS/DASH mux + libavcodec-dev + libavutil-dev + ffmpeg # MEDIA (M4): runtime muxer +) + +APT_GUI=( + qt6-base-dev + qt6-tools-dev + qt6-tools-dev-tools # lrelease/lupdate for i18n + libqt6svg6-dev # GUI: SVG icon rendering +) + +APT_LINT=( + clang-format + clang-tidy +) + +APT_NODE=( + nodejs # EXT + tools/mockd + conformance runner + npm +) + +APT_CLANG=( + clang # optional: libFuzzer targets (M7) + llvm +) + +APT_PACKAGING=( + debhelper + dpkg-dev + lintian + devscripts + fakeroot +) + +# --- install -------------------------------------------------------------------- + +PKGS=("${APT_CORE[@]}" "${APT_LIBS[@]}" "${APT_GUI[@]}" "${APT_LINT[@]}" "${APT_NODE[@]}") +[[ $WITH_CLANG -eq 1 ]] && PKGS+=("${APT_CLANG[@]}") +[[ $WITH_PACKAGING -eq 1 ]] && PKGS+=("${APT_PACKAGING[@]}") + +if [[ $CHECK_ONLY -eq 0 ]]; then + log "apt-get update" + $SUDO apt-get update -qq + log "installing ${#PKGS[@]} packages (idempotent; already-present ones are skipped)" + DEBIAN_FRONTEND=noninteractive $SUDO apt-get install -y --no-install-recommends "${PKGS[@]}" +else + log "--check: skipping installation" +fi + +# --- verify -------------------------------------------------------------------- + +log "verifying toolchain" + +fail=0 +need_cmd() { + if command -v "$1" >/dev/null 2>&1; then + printf ' \033[32m✓\033[0m %-16s %s\n' "$1" "$("${@:2}" 2>&1 | head -1)" + else + printf ' \033[31m✗\033[0m %-16s MISSING\n' "$1" + fail=1 + fi +} + +need_cmd git git --version +need_cmd cmake cmake --version +need_cmd ninja ninja --version +need_cmd g++ g++ --version +need_cmd pkg-config pkg-config --version +need_cmd python3 python3 --version +need_cmd clang-format clang-format --version +need_cmd clang-tidy clang-tidy --version +need_cmd node node --version +need_cmd npm npm --version +[[ $WITH_CLANG -eq 1 ]] && need_cmd clang clang --version + +# Version floors that actually matter. +if command -v cmake >/dev/null 2>&1; then + cmake_ver="$(cmake --version | sed -n '1s/.* //p')" + # `sort -V -C` exits 0 iff the input is already in ascending order, i.e. floor <= ver. + if ! printf '3.28.0\n%s\n' "$cmake_ver" | sort -V -C; then + warn "cmake $cmake_ver is below the 3.28 floor in CMakeLists.txt." + fi + # CMake >= 4 hard-errors on cmake_minimum_required() < 3.5 in any dependency. + if printf '4.0.0\n%s\n' "$cmake_ver" | sort -V -C; then + log "cmake $cmake_ver is 4.x — dependencies with a pre-3.5 CMake floor will fail to configure." + fi +fi + +if command -v g++ >/dev/null 2>&1; then + gxx_major="$(g++ -dumpversion | cut -d. -f1)" + if (( gxx_major < 13 )); then + warn "g++ $gxx_major lacks the C++23 support this project needs (>= 13)." + fi + echo '#include +#include +#if __cpp_lib_expected < 202202L +#error no std::expected +#endif +int main(){}' > /tmp/vdm_bootstrap_cxx23.$$.cpp + if g++ -std=c++23 -fsyntax-only /tmp/vdm_bootstrap_cxx23.$$.cpp 2>/dev/null; then + printf ' \033[32m✓\033[0m %-16s std::expected / -std=c++23 OK\n' "c++23" + else + printf ' \033[31m✗\033[0m %-16s -std=c++23 with failed\n' "c++23" + fail=1 + fi + rm -f /tmp/vdm_bootstrap_cxx23.$$.cpp +fi + +if command -v node >/dev/null 2>&1; then + node_major="$(node --version | sed 's/^v//; s/\..*//')" + if (( node_major < 20 )); then + warn "node $node_major may be too old for the extension toolchain; consider nvm (>= 20)." + fi +fi + +# Qt / library dev packages: check via pkg-config where possible. +for mod in Qt6Core Qt6Widgets Qt6Svg libcurl sqlite3 libssl libsecret-1 libavformat; do + if pkg-config --exists "$mod" 2>/dev/null; then + printf ' \033[32m✓\033[0m %-16s %s\n' "$mod" "$(pkg-config --modversion "$mod")" + else + printf ' \033[31m✗\033[0m %-16s pkg-config can'\''t find it\n' "$mod" + fail=1 + fi +done + +echo +if [[ $fail -ne 0 ]]; then + die "toolchain incomplete — see the ✗ lines above." +fi +log "toolchain OK. Next: cmake --preset dev && cmake --build --preset dev"