From 7580f2c313d96422a169d43e1366d88264d3edbf Mon Sep 17 00:00:00 2001 From: Nathan Slaven Date: Wed, 25 Feb 2026 04:39:47 +0000 Subject: [PATCH] Installer: add cross-compiled Qt wallet support (win64, win32, armhf, aarch64) with --qt-target; update tests and docs --- doc/installer.md | 166 ++++++++++++++++ installer/agrarian-installer.sh | 328 +++++++++++++++++++++++++++++--- installer/tests/run.sh | 100 ++++++++-- 3 files changed, 555 insertions(+), 39 deletions(-) create mode 100644 doc/installer.md diff --git a/doc/installer.md b/doc/installer.md new file mode 100644 index 00000000..f16220a9 --- /dev/null +++ b/doc/installer.md @@ -0,0 +1,166 @@ +Installer (Ubuntu) +================== + +Overview +--------------------- +The Agrarian installer is `installer/agrarian-installer.sh`. It automates the Ubuntu build steps by: + +- Building the deterministic `depends/` prefix (`make -C depends HOST=... USE_WALLET=... -j...`). +- Configuring the project with the depends `config.site` and prefix. +- Building the daemon and CLI utilities (via `--action daemon` or `--action all`). +- Building the Qt wallet on Linux hosts (via `--action qt`, or `--action all` when Qt is enabled). +- Cross-compiling Qt wallets for Windows and Linux ARM targets (via `--action qt --qt-target ...`). + +It does not: + +- Install system packages (it only checks for required toolchains and prints an `apt-get` command if missing). +- Run `make install` or copy binaries into `/usr/local`. +- Package platform installers (e.g., Windows/macOS/ARM Qt wallet bundles). +- Run or configure the daemon after the build. + +Quick Start (Ubuntu/Debian) +--------------------- +Clone the repo and enter it (standard `git clone` workflow), then: + +Show installer help: + +```bash +./installer/agrarian-installer.sh --help +``` + +Build the daemon (runs depends, configure, then `make -C src agrariand`): + +```bash +./installer/agrarian-installer.sh --action daemon +``` + +Build the Qt wallet on Linux (runs depends Qt target when `HOST` is Linux, then `make -C src/qt agrarian-qt`): + +```bash +./installer/agrarian-installer.sh --action qt +``` + +Build Qt wallets for cross targets (examples): + +```bash +./installer/agrarian-installer.sh --action qt --qt-target win64 +./installer/agrarian-installer.sh --action qt --qt-target win32 +./installer/agrarian-installer.sh --action qt --qt-target armhf +./installer/agrarian-installer.sh --action qt --qt-target aarch64 +./installer/agrarian-installer.sh --action qt --qt-target all +``` + +Expected outputs: + +- Depends prefix: `depends//` +- Daemon: `src/agrariand` +- CLI utilities (when using `--action all` or a full top-level build): `src/agrarian-cli`, `src/agrarian-tx` +- Qt wallet (Linux): `src/qt/agrarian-qt` +- Qt wallet (Windows): `src/qt/agrarian-qt.exe` + +Run the daemon: + +```bash +./src/agrariand +``` + +Common Installer Options +--------------------- +`--action ` + +- `depends` builds only the `depends/` prefix. +- `daemon` builds the daemon (`src/agrariand`). If depends are missing, the installer builds them first. +- `qt` builds the Qt wallet (`src/qt/agrarian-qt`). If depends are missing, the installer builds them first. +- `all` builds depends and then runs top-level `make` in the repo root. + +`--qt-target ` + +- `native` uses `--host` as-is (default). +- `win64` maps to `x86_64-w64-mingw32`. +- `win32` maps to `i686-w64-mingw32`. +- `armhf` maps to `arm-linux-gnueabihf`. +- `aarch64` maps to `aarch64-unknown-linux-gnu`. +- `all` builds native + all cross targets listed above. + +`--host ` + +- Sets the build host triplet (default: `x86_64-pc-linux-gnu`). +- Passed to `depends` as `HOST=`. + +`--wallet <0|1>` + +- Controls wallet support. +- Passed to `depends` as `USE_WALLET=<0|1>`. +- When `--wallet 0`, the installer also adds `--disable-wallet` during `configure`. + +`--dry-run` + +- Prints the commands the installer would run, without executing them. + +`NO_QT=1` in depends + +- The installer does not expose `NO_QT`. +- If you need to skip Qt in depends, run it manually: + +```bash +make -C depends HOST=x86_64-pc-linux-gnu NO_QT=1 +``` + +Troubleshooting +--------------------- +Boost library naming/layout (the `-mt` suffix) + +- Depends builds may produce Boost libs with suffixes like `libboost_thread-gcc-mt-1_64.a`. +- The installer checks for `libboost_thread*.a` and `libboost_system*.a`, so it tolerates `-mt` and versioned names. +- If you are configuring manually, keep `--with-boost=` (the installer sets this for you) to avoid system Boost fallback. + +`config.site` and PATH pitfalls + +- The installer configures with `CONFIG_SITE=depends//share/config.site`. +- That `config.site` prepends `depends//native/bin` to `PATH`. Do not overwrite `PATH` with a minimal value; ensure `/usr/bin` and other system paths remain available. +- If `config.site` is missing, rebuild depends: + +```bash +./installer/agrarian-installer.sh --action depends +``` + +Qt pkg-config files missing in the depends prefix + +The installer requires these `.pc` files in `depends//(lib|share)/pkgconfig`: + +- `Qt5Core.pc` +- `Qt5Gui.pc` +- `Qt5Network.pc` +- `Qt5Widgets.pc` + +Fix by rebuilding depends with Qt enabled: + +```bash +./installer/agrarian-installer.sh --action qt +``` + +Forcing rebuilds + +- Use `--reset-depends` to delete `depends/work`, `depends/built`, and `depends/`, then re-run the installer action you need. +- If you need a fresh depends build without deleting the prefix, re-run the depends build (same command the installer prints on failure): + +```bash +make -C depends HOST= USE_WALLET= -j +``` + +Qt Cross-Compilation Packages (Ubuntu/Debian) +--------------------- +Install the common Linux build tools (from `depends/README.md`): + +```bash +sudo apt-get install make automake cmake curl g++-multilib libtool binutils-gold bsdmainutils pkg-config python3 patch +``` + +Then install toolchains per target: + +- win64: `g++-mingw-w64-x86-64` (see `doc/build-windows.md`) +- win32: `g++-mingw-w64-i686` (see `doc/build-windows.md`) +- armhf: `g++-arm-linux-gnueabihf` and `binutils-arm-linux-gnueabihf` +- aarch64: `g++-aarch64-linux-gnu` and `binutils-aarch64-linux-gnu` + +If any toolchain binaries are missing, the installer prints a single `apt-get install` command that includes the required packages for the selected Qt targets. diff --git a/installer/agrarian-installer.sh b/installer/agrarian-installer.sh index 3a52baeb..e903c322 100755 --- a/installer/agrarian-installer.sh +++ b/installer/agrarian-installer.sh @@ -6,6 +6,7 @@ REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)" HOST="x86_64-pc-linux-gnu" ACTION="all" +QT_TARGET="native" WALLET="1" JOBS="$(nproc)" DO_UPDATE=0 @@ -13,6 +14,8 @@ RESET_DEPENDS=0 ASSUME_YES=0 USER_LOG_PATH="" TEST_MODE="${AGRARIAN_INSTALLER_TEST_MODE:-0}" +DRY_RUN="0" +SUPPORTED_HOSTS=() usage() { cat <<'USAGE' @@ -24,12 +27,15 @@ Options: --host Build host triplet (default: x86_64-pc-linux-gnu) --action Action to run (default: all) + --qt-target + Qt wallet target (default: native) --wallet <0|1> Enable wallet-related dependencies/build flags (default: 1) --jobs Parallel build jobs (default: nproc) --update Run git pull --rebase before build --reset-depends Remove depends/work, depends/built, depends/ --yes Assume yes for prompts --log Log output path + --dry-run Print commands without executing them -h, --help Show this help USAGE } @@ -39,6 +45,12 @@ fail() { exit 1 } +join_by() { + local IFS="$1" + shift + echo "$*" +} + check_ubuntu() { if [[ ! -r /etc/os-release ]]; then fail "Cannot verify OS (missing /etc/os-release); Ubuntu is required" @@ -71,13 +83,110 @@ confirm() { run_cmd() { echo "+ $*" - if [[ "$TEST_MODE" == "1" ]]; then - echo "[test-mode] skipped" + if is_dry_run; then + echo "[dry-run] skipped" return 0 fi "$@" } +detect_supported_hosts() { + local host_dir="${REPO_ROOT}/depends/hosts" + local name + local skip + local generic + local known_generics=("default" "linux" "mingw32" "darwin") + + [[ -d "${host_dir}" ]] || fail "Missing depends hosts directory: ${host_dir}" + + SUPPORTED_HOSTS=() + for path in "${host_dir}"/*.mk; do + [[ -f "${path}" ]] || continue + name="$(basename "${path}" .mk)" + skip=0 + for generic in "${known_generics[@]}"; do + if [[ "${name}" == "${generic}" ]]; then + skip=1 + break + fi + done + (( skip == 0 )) && SUPPORTED_HOSTS+=("${name}") + done + + ((${#SUPPORTED_HOSTS[@]} > 0)) || fail "No supported host definitions found in ${host_dir}" +} + +ensure_supported_host() { + local host="$1" + local supported + supported="$(join_by ", " "${SUPPORTED_HOSTS[@]}")" + if [[ ! " ${SUPPORTED_HOSTS[*]} " =~ [[:space:]]${host}[[:space:]] ]]; then + fail "Unsupported host '${host}'. Supported hosts: ${supported}" + fi +} + +add_missing_toolchain() { + local tool="$1" + local package="$2" + + if ! command -v "${tool}" >/dev/null 2>&1; then + MISSING_TOOLS+=("${tool}") + MISSING_PACKAGES+=("${package}") + fi +} + +check_toolchains_for_host() { + local host="$1" + case "${host}" in + x86_64-w64-mingw32) + add_missing_toolchain "x86_64-w64-mingw32-g++" "g++-mingw-w64-x86-64" + ;; + i686-w64-mingw32) + add_missing_toolchain "i686-w64-mingw32-g++" "g++-mingw-w64-i686" + ;; + arm-linux-gnueabihf) + add_missing_toolchain "arm-linux-gnueabihf-g++" "g++-arm-linux-gnueabihf" + add_missing_toolchain "arm-linux-gnueabihf-ar" "binutils-arm-linux-gnueabihf" + ;; + aarch64-unknown-linux-gnu) + add_missing_toolchain "aarch64-linux-gnu-g++" "g++-aarch64-linux-gnu" + add_missing_toolchain "aarch64-linux-gnu-ar" "binutils-aarch64-linux-gnu" + ;; + *) + ;; + esac +} + +ensure_toolchains_for_hosts() { + local hosts=("$@") + local unique_packages=() + local host + local pkg + + MISSING_TOOLS=() + MISSING_PACKAGES=() + + for host in "${hosts[@]}"; do + check_toolchains_for_host "${host}" + done + + if ((${#MISSING_TOOLS[@]} == 0)); then + return 0 + fi + + for pkg in "${MISSING_PACKAGES[@]}"; do + if [[ ! " ${unique_packages[*]} " =~ [[:space:]]${pkg}[[:space:]] ]]; then + unique_packages+=("${pkg}") + fi + done + + echo "ERROR: Missing required cross toolchain binaries:" >&2 + printf ' - %s\n' "${MISSING_TOOLS[@]}" >&2 + echo "Install with:" >&2 + echo " sudo apt-get update && sudo apt-get install -y $(join_by " " "${unique_packages[@]}")" >&2 + exit 1 +} + ensure_configure() { if [[ ! -x "${REPO_ROOT}/configure" ]]; then run_cmd "${REPO_ROOT}/autogen.sh" @@ -98,17 +207,27 @@ reset_depends_paths() { } build_depends() { - local args=("HOST=${HOST}" "-j${JOBS}") - if [[ "$WALLET" == "0" ]]; then - args+=("USE_WALLET=0") - fi + local host="$1" + local args=("HOST=${host}" "USE_WALLET=${WALLET}" "-j${JOBS}") + run_cmd make -C "${REPO_ROOT}/depends" "${args[@]}" +} + +build_depends_qt() { + local host="$1" + local args=("HOST=${host}" "USE_WALLET=${WALLET}" "-j${JOBS}" "qt") run_cmd make -C "${REPO_ROOT}/depends" "${args[@]}" } ensure_depends_prereqs() { - local prefix="${REPO_ROOT}/depends/${HOST}" + local host="$1" + local prefix="${REPO_ROOT}/depends/${host}" local missing=() + if is_dry_run; then + echo "[dry-run] skipping depends prefix checks for ${host}" + return 0 + fi + [[ -f "${prefix}/share/config.site" ]] || missing+=("${prefix}/share/config.site") [[ -f "${prefix}/include/boost/thread.hpp" ]] || missing+=("${prefix}/include/boost/thread.hpp") @@ -127,41 +246,172 @@ ensure_depends_prereqs() { if (( ${#missing[@]} > 0 )); then echo "ERROR: depends prefix is missing required files:" >&2 printf ' - %s\n' "${missing[@]}" >&2 - echo "Fix: make -C ${REPO_ROOT}/depends HOST=${HOST} USE_WALLET=${WALLET} -j${JOBS}" >&2 + echo "Fix: make -C ${REPO_ROOT}/depends HOST=${host} USE_WALLET=${WALLET} -j${JOBS}" >&2 + exit 1 + fi +} + +ensure_qt_pkgconfig_prereqs() { + local host="$1" + local prefix="${REPO_ROOT}/depends/${host}" + local missing=() + local module + local found_path + + if is_dry_run; then + echo "[dry-run] skipping Qt pkg-config checks for ${host}" + return 0 + fi + + for module in Qt5Core Qt5Gui Qt5Network Qt5Widgets; do + found_path="" + if [[ -f "${prefix}/lib/pkgconfig/${module}.pc" ]]; then + found_path="${prefix}/lib/pkgconfig/${module}.pc" + elif [[ -f "${prefix}/share/pkgconfig/${module}.pc" ]]; then + found_path="${prefix}/share/pkgconfig/${module}.pc" + fi + [[ -n "${found_path}" ]] || missing+=("${module}.pc in ${prefix}/(lib|share)/pkgconfig") + done + + if (( ${#missing[@]} > 0 )); then + echo "ERROR: Qt pkg-config files are missing from depends prefix:" >&2 + printf ' - %s\n' "${missing[@]}" >&2 + echo "Fix: make -C ${REPO_ROOT}/depends HOST=${host} USE_WALLET=${WALLET} -j${JOBS} qt" >&2 exit 1 fi } configure_project() { local mode="$1" - local config_site="${REPO_ROOT}/depends/${HOST}/share/config.site" - local cfg_args=("--prefix=${REPO_ROOT}/depends/${HOST}") + local host="$2" + local config_site="${REPO_ROOT}/depends/${host}/share/config.site" + local cfg_args=( + "--build=${host}" + "--host=${host}" + "--prefix=${REPO_ROOT}/depends/${host}" + "--with-boost=${REPO_ROOT}/depends/${host}" + ) [[ "$WALLET" == "0" ]] && cfg_args+=("--disable-wallet") [[ "$mode" == "daemon" ]] && cfg_args+=("--without-gui") ensure_configure - ensure_depends_prereqs + ensure_depends_prereqs "${host}" run_cmd env CONFIG_SITE="${config_site}" "${REPO_ROOT}/configure" "${cfg_args[@]}" } build_daemon() { - configure_project daemon + configure_project daemon "${HOST}" run_cmd make -C "${REPO_ROOT}/src" "-j${JOBS}" agrariand } -build_qt() { - configure_project qt +qt_target_host() { + local target="$1" + case "${target}" in + native) + echo "${HOST}" + ;; + win64) + echo "x86_64-w64-mingw32" + ;; + win32) + echo "i686-w64-mingw32" + ;; + armhf) + echo "arm-linux-gnueabihf" + ;; + aarch64) + echo "aarch64-unknown-linux-gnu" + ;; + *) + return 1 + ;; + esac +} + +qt_target_output() { + local host="$1" + if [[ "${host}" == *mingw32 ]]; then + echo "${REPO_ROOT}/src/qt/agrarian-qt.exe" + else + echo "${REPO_ROOT}/src/qt/agrarian-qt" + fi +} + +qt_target_list() { + local target="$1" + case "${target}" in + all) + echo "native win64 win32 armhf aarch64" + ;; + *) + echo "${target}" + ;; + esac +} + +build_qt_for_host() { + local target="$1" + local host="$2" + local prefix="${REPO_ROOT}/depends/${host}" + local output_path + + output_path="$(qt_target_output "${host}")" + + echo "Qt wallet build target:" + echo " target: ${target}" + echo " host: ${host}" + echo " depends prefix: ${prefix}" + echo " output: ${output_path}" + + build_depends_qt "${host}" + ensure_qt_pkgconfig_prereqs "${host}" + configure_project qt "${host}" run_cmd make -C "${REPO_ROOT}/src/qt" "-j${JOBS}" agrarian-qt } +build_qt() { + local target + local host + local qt_targets + local unique_hosts=() + local entry + + qt_targets="$(qt_target_list "${QT_TARGET}")" + for target in ${qt_targets}; do + host="$(qt_target_host "${target}")" + if [[ -z "${host}" ]]; then + fail "Invalid --qt-target value: ${target}" + fi + for entry in "${unique_hosts[@]}"; do + if [[ "${entry}" == "${host}" ]]; then + host="" + break + fi + done + [[ -n "${host}" ]] && unique_hosts+=("${host}") + done + + ensure_toolchains_for_hosts "${unique_hosts[@]}" + + for target in ${qt_targets}; do + host="$(qt_target_host "${target}")" + build_qt_for_host "${target}" "${host}" + done +} + build_all() { - configure_project all + configure_project all "${HOST}" run_cmd make -C "${REPO_ROOT}" "-j${JOBS}" } needs_depends() { - [[ ! -f "${REPO_ROOT}/depends/${HOST}/share/config.site" ]] + local host="$1" + [[ ! -f "${REPO_ROOT}/depends/${host}/share/config.site" ]] +} + +is_dry_run() { + [[ "${TEST_MODE}" == "1" || "${DRY_RUN}" == "1" ]] } while [[ $# -gt 0 ]]; do @@ -176,6 +426,11 @@ while [[ $# -gt 0 ]]; do ACTION="$2" shift 2 ;; + --qt-target) + [[ $# -ge 2 ]] || fail "Missing value for --qt-target" + QT_TARGET="$2" + shift 2 + ;; --wallet) [[ $# -ge 2 ]] || fail "Missing value for --wallet" WALLET="$2" @@ -203,6 +458,11 @@ while [[ $# -gt 0 ]]; do USER_LOG_PATH="$2" shift 2 ;; + --dry-run) + DRY_RUN=1 + TEST_MODE=1 + shift + ;; -h|--help) usage exit 0 @@ -218,6 +478,11 @@ case "$ACTION" in *) fail "Invalid --action: ${ACTION}" ;; esac +case "$QT_TARGET" in + native|win64|win32|armhf|aarch64|all) ;; + *) fail "Invalid --qt-target: ${QT_TARGET}" ;; +esac + case "$WALLET" in 0|1) ;; *) fail "Invalid --wallet value: ${WALLET} (expected 0 or 1)" ;; @@ -241,14 +506,32 @@ echo "Agrarian installer" echo " repo: ${REPO_ROOT}" echo " host: ${HOST}" echo " action: ${ACTION}" +echo " qt_target: ${QT_TARGET}" echo " wallet: ${WALLET}" echo " jobs: ${JOBS}" echo " update: ${DO_UPDATE}" echo " reset_depends: ${RESET_DEPENDS}" -echo " test_mode: ${TEST_MODE}" +echo " dry_run: $(is_dry_run && echo 1 || echo 0)" echo " log: ${LOG_PATH}" check_ubuntu +detect_supported_hosts + +if [[ "${ACTION}" != "qt" && "${QT_TARGET}" != "native" ]]; then + fail "--qt-target is only supported with --action qt" +fi + +if [[ "${ACTION}" == "qt" ]]; then + qt_targets="$(qt_target_list "${QT_TARGET}")" + for target in ${qt_targets}; do + host="$(qt_target_host "${target}")" + [[ -n "${host}" ]] || fail "Invalid --qt-target value: ${target}" + ensure_supported_host "${host}" + done +else + ensure_supported_host "${HOST}" + ensure_toolchains_for_hosts "${HOST}" +fi confirm "Proceed with selected installer action?" @@ -263,22 +546,19 @@ fi case "$ACTION" in depends) - build_depends + build_depends "${HOST}" ;; daemon) - if needs_depends; then - build_depends + if needs_depends "${HOST}"; then + build_depends "${HOST}" fi build_daemon ;; qt) - if needs_depends; then - build_depends - fi build_qt ;; all) - build_depends + build_depends "${HOST}" build_all ;; esac diff --git a/installer/tests/run.sh b/installer/tests/run.sh index 59205d69..988045ec 100755 --- a/installer/tests/run.sh +++ b/installer/tests/run.sh @@ -32,6 +32,20 @@ exit 0 SH chmod +x "${FAKE_BIN}/make" +for tool in \ + x86_64-w64-mingw32-g++ \ + i686-w64-mingw32-g++ \ + aarch64-linux-gnu-gcc \ + aarch64-linux-gnu-g++ \ + arm-linux-gnueabihf-gcc \ + arm-linux-gnueabihf-g++; do + cat > "${FAKE_BIN}/${tool}" <<'SH' +#!/usr/bin/env bash +exit 0 +SH + chmod +x "${FAKE_BIN}/${tool}" +done + assert_file_nonempty() { local path="$1" local i @@ -45,9 +59,32 @@ assert_file_nonempty() { exit 1 } +seed_fake_depends_prefix() { + local host="$1" + local prefix="${WORK_REPO}/depends/${host}" + mkdir -p "${prefix}/share" "${prefix}/include/boost" "${prefix}/lib" "${prefix}/lib/pkgconfig" + : > "${prefix}/share/config.site" + : > "${prefix}/include/boost/thread.hpp" + : > "${prefix}/include/db_cxx.h" + : > "${prefix}/lib/libboost_thread.a" + : > "${prefix}/lib/libboost_system.a" + : > "${prefix}/lib/pkgconfig/Qt5Core.pc" + : > "${prefix}/lib/pkgconfig/Qt5Gui.pc" + : > "${prefix}/lib/pkgconfig/Qt5Network.pc" + : > "${prefix}/lib/pkgconfig/Qt5Widgets.pc" +} + echo "[test 1] help output works" bash "${WORK_REPO}/installer/agrarian-installer.sh" --help > "${LOG_DIR}/help.out" rg -q -- "--action " "${LOG_DIR}/help.out" +rg -q -- "--qt-target " "${LOG_DIR}/help.out" +rg -q -- "--host " "${LOG_DIR}/help.out" +rg -q -- "--wallet <0|1>" "${LOG_DIR}/help.out" +rg -q -- "--jobs " "${LOG_DIR}/help.out" +rg -q -- "--reset-depends" "${LOG_DIR}/help.out" +rg -q -- "--update" "${LOG_DIR}/help.out" +rg -q -- "--yes" "${LOG_DIR}/help.out" +rg -q -- "--dry-run" "${LOG_DIR}/help.out" echo "[test 2] depends build for x86_64-pc-linux-gnu succeeds" DEPENDS_LOG="${LOG_DIR}/depends.log" @@ -58,25 +95,42 @@ PATH="${FAKE_BIN}:${PATH}" AGRARIAN_FAKE_MAKE_LOG="${FAKE_MAKE_LOG}" bash "${WOR --yes \ --log "${DEPENDS_LOG}" assert_file_nonempty "${DEPENDS_LOG}" -rg -q -- "-C ${WORK_REPO}/depends HOST=x86_64-pc-linux-gnu -j2" "${FAKE_MAKE_LOG}" +rg -q -- "-C ${WORK_REPO}/depends HOST=x86_64-pc-linux-gnu USE_WALLET=1 -j2" "${FAKE_MAKE_LOG}" -echo "[test 3] can run twice with --reset-depends" -for i in 1 2; do - RESET_LOG="${LOG_DIR}/reset-${i}.log" - AGRARIAN_INSTALLER_TEST_MODE=1 bash "${WORK_REPO}/installer/agrarian-installer.sh" \ - --action depends \ - --host x86_64-pc-linux-gnu \ - --jobs 2 \ - --reset-depends \ - --yes \ - --log "${RESET_LOG}" - assert_file_nonempty "${RESET_LOG}" -done +echo "[test 3] wallet=0 maps to USE_WALLET=0 for depends" +DEPENDS_W0_LOG="${LOG_DIR}/depends-wallet0.log" +PATH="${FAKE_BIN}:${PATH}" AGRARIAN_FAKE_MAKE_LOG="${FAKE_MAKE_LOG}" bash "${WORK_REPO}/installer/agrarian-installer.sh" \ + --action depends \ + --host x86_64-pc-linux-gnu \ + --wallet 0 \ + --jobs 2 \ + --yes \ + --log "${DEPENDS_W0_LOG}" +assert_file_nonempty "${DEPENDS_W0_LOG}" +rg -q -- "-C ${WORK_REPO}/depends HOST=x86_64-pc-linux-gnu USE_WALLET=0 -j2" "${FAKE_MAKE_LOG}" -echo "[test 4] all actions produce logs and return 0" +echo "[test 4] reset-depends only removes allowed paths" +mkdir -p "${WORK_REPO}/depends/work" "${WORK_REPO}/depends/built" "${WORK_REPO}/depends/x86_64-pc-linux-gnu" "${WORK_REPO}/user-runtime-data" +: > "${WORK_REPO}/user-runtime-data/keep-me" +RESET_LOG="${LOG_DIR}/reset.log" +PATH="${FAKE_BIN}:${PATH}" AGRARIAN_INSTALLER_TEST_MODE=1 bash "${WORK_REPO}/installer/agrarian-installer.sh" \ + --action depends \ + --host x86_64-pc-linux-gnu \ + --jobs 2 \ + --reset-depends \ + --yes \ + --log "${RESET_LOG}" +assert_file_nonempty "${RESET_LOG}" +[[ ! -d "${WORK_REPO}/depends/work" ]] +[[ ! -d "${WORK_REPO}/depends/built" ]] +[[ ! -d "${WORK_REPO}/depends/x86_64-pc-linux-gnu" ]] +[[ -f "${WORK_REPO}/user-runtime-data/keep-me" ]] + +echo "[test 5] all actions produce logs and return 0" +seed_fake_depends_prefix "x86_64-pc-linux-gnu" for action in depends daemon qt all; do ACTION_LOG="${LOG_DIR}/${action}.log" - AGRARIAN_INSTALLER_TEST_MODE=1 bash "${WORK_REPO}/installer/agrarian-installer.sh" \ + PATH="${FAKE_BIN}:${PATH}" AGRARIAN_INSTALLER_TEST_MODE=1 bash "${WORK_REPO}/installer/agrarian-installer.sh" \ --action "${action}" \ --host x86_64-pc-linux-gnu \ --jobs 2 \ @@ -85,4 +139,20 @@ for action in depends daemon qt all; do assert_file_nonempty "${ACTION_LOG}" done +echo "[test 6] dry-run qt win64 prints expected commands" +QT_DRY_LOG="${LOG_DIR}/qt-win64-dry.log" +PATH="${FAKE_BIN}:${PATH}" bash "${WORK_REPO}/installer/agrarian-installer.sh" \ + --action qt \ + --qt-target win64 \ + --jobs 2 \ + --yes \ + --dry-run \ + --log "${QT_DRY_LOG}" +assert_file_nonempty "${QT_DRY_LOG}" +rg -q -- "\\+ make -C ${WORK_REPO}/depends HOST=x86_64-w64-mingw32 USE_WALLET=1 -j2 qt" "${QT_DRY_LOG}" +rg -q -- "CONFIG_SITE=${WORK_REPO}/depends/x86_64-w64-mingw32/share/config.site" "${QT_DRY_LOG}" +rg -q -- "--build=x86_64-w64-mingw32" "${QT_DRY_LOG}" +rg -q -- "--host=x86_64-w64-mingw32" "${QT_DRY_LOG}" +rg -q -- "\\+ make -C ${WORK_REPO}/src/qt -j2 agrarian-qt" "${QT_DRY_LOG}" + echo "All installer tests passed."