Repository navigation
Conversation
added 18 commits
November 1, 2026 20:15
Adds a Makefile that wraps scripts/build_app.sh: - make build-macos runs the same steps as CI (build_app.sh, pub get, prebuild.sh, flutter build macos). PREBUILTS=0 compiles native assets from source (the generated pubspec.yaml is removed first so an earlier -d run does not stick). Produces the same app as upstream (Stack Wallet.app, com.cypherstack.stack_wallet). - make bootstrap-macos (Homebrew; pins Flutter 3.47.2), nix develop via flake.nix/.envrc (sets FLUTTER_ROOT so `dart run` works), make bootstrap-xcode, and an opt-in make bootstrap-xcode-download (archive.org; SHA-1 and Apple signature are both checked). - make sccache-setup (opt-in): sccache for native-asset hook builds via ~/.cargo/config.toml. - make build-linux; writes a git-ignored .cargo/config.toml with PROTOC so crates that ship a generic-Linux protoc build on NixOS. - bm/ benchmark scripts and MWC integration tests. Docs: new "Building with make" section in docs/building.md. Verified (one machine each, one run): - macOS 27.2 / Xcode 27.1: make build-macos from a clean checkout (946 s cold, 319.0 MB), PREBUILTS=0 (596 s), and inside nix develop (Flutter 3.47.4, 261 s). - Linux: NixOS x86_64, nix develop, Rust 1.99.1, make build-linux produced build/linux/x64/release/bundle/stack_wallet (291 MB). - Xcode 27.1 download from archive.org: SHA-1 and pkgutil signature check pass (install step not run). Not tested: Ubuntu, Windows, Android, iOS, bootstrap-macos on a fresh Mac.
…set hooks Measured on macOS with the unmodified upstream tree: a repeated build takes 33-40 s with an unchanged environment, but 536 s after one extra directory in PATH and 156-164 s after adding a NIX_* variable or restoring PATH, because hooks_runner reruns every hook when the environment it hashes changes.
download_xcode.sh used sudo for rm/mv/xattr unconditionally. It now checks whether the parent of the target directory is writable and only then uses sudo, so Xcode can be installed into ~/Applications without a password. Verified on macOS 27.2: -d ~/Applications/Xcode_27.1_test.app installed Xcode 27.1 (27A9275), the extracted app has no quarantine attribute, and free space dropped by about 4 GB; hash and signature checks passed before it. The install-time prompt text now says about 20 GB free are needed.
…ptional install_macos_build_tools.sh aborted at the first brew failure. On a machine where weasyprint was installed another way, brew could not link it, set -e stopped the script, and the Flutter step was never reached. It also upgraded formulae that were already installed (cmake, go), changing the build machine under the user. - export HOMEBREW_NO_INSTALL_UPGRADE=1 for the required packages - install pandoc/weasyprint/toilet/figlet (only used by the bm/ report rendering) in a separate, non-fatal step Verified on macOS 27.2: first run failed as described; after the change the installer ended with rc=0, cloned Flutter 3.47.4 into a temporary FLUTTER_DIR, left the existing Flutter 3.47.2 untouched, and only appended the brew shellenv and Flutter PATH lines to ~/.zshrc (restored afterwards).
…lock make build-macos now runs ./build_app.sh from the scripts directory (as the CI jobs and the other targets do), so scripts/build_app.sh stays exactly as in staging; the earlier path-resolution and variable-rename edits are reverted. make build-linux no longer recreates lib/external_api_keys.dart: prebuild.sh already creates it, and the block never ran in any of the Linux builds I did. Verified on macOS 27.2: make build-macos OK, Stack Wallet.app with the unchanged bundle ID. The Linux target was only checked with make -n after this change.
archive.org sometimes resets the connection (curl exit 56) a minute into the transfer, which aborted the script even though the download can be resumed. curl now retries up to 8 times (--retry-all-errors) and resumes with -C -. Seen in a fresh macOS 27.2 VM; the retry itself is exercised in the next VM run.
…e, docs make build-linux now passes -d (PREBUILTS=1, the default, like make build-macos and the CI job) and -s with SYSTEM_DEPS=1. With -s the Makefile sets only USE_SYSTEM_SECURE_STORAGE_DEPS=1 for the app build; the local libsecret pkg-config override is kept for the default path (it is needed where libsecret is built from source, for example on NixOS). download_xcode.sh accepts XCODE_XIP_URL to download from another mirror; the SHA-1 and the Apple signature are still checked. docs: a second Xcode via DEVELOPER_DIR, and what reaches the hooks for sccache (exported RUSTC_WRAPPER does not, the cargo config file does). Verified: NixOS (nix develop) make build-linux with -d builds the bundle; Ubuntu 24.04 container make build-linux SYSTEM_DEPS=1 (-d -s, the CI flags) builds the bundle; make -n and bash -n pass for all targets and scripts.
… bm/bench.sh clean-app removes build/ and the Pods but keeps .dart_tool/hooks_runner, so the next build does not rebuild the native assets; clean-native removes only the native-asset outputs. bm/bench.sh zeroes the sccache statistics before the build and stores 'sccache hits/executed requests' in the comment column of the CSV.
stack-bom.toml records the expected toolchain (Flutter, Dart, Rust, Go, Xcode) and the git revisions of the pinned native plugins. make verify-bom (dart tool/verify_bom.dart, no packages needed) checks the local machine and pubspec.lock against it: a mismatch in Rust, Dart, minimum Flutter/Go or a plugin pin fails, a different recommended Flutter or Xcode only warns. dart tool/verify_bom.dart --update regenerates the [plugins] section from pubspec.lock. Verified on macOS 27.2: passes with 1 warning (Flutter 3.47.2 vs. recommended 3.47.4); a wrong Rust version and a wrong plugin pin both exit 1.
…targets make build-windows wraps the steps of the build-windows CI job (prebuild.sh, build_app.sh -p windows -d -s, pub get, coinlib:build_windows, flutter build windows). WINDOWS_COPY_ASSETS=1 replaces the asset links with copies for runners that cannot create symlinks. .github/workflows/make-build.yaml runs make build-windows and make build-macos on hosted runners (manual dispatch or pushes to ci/make-* branches).
…ing key exists The release build fails at packageRelease without android/key.properties (SigningConfig release is missing storeFile). android-dev-key creates a debug keystore and key.properties for local builds only; both files are git-ignored and the APKs are not for distribution.
…deps and bm - build-windows: with WINDOWS_COPY_ASSETS=1 remove the asset copies of an earlier run before build_app.sh runs link_assets.sh, whose `rm -f` cannot delete real directories (second run failed) - bootstrap-macos: skip the Homebrew installer in a Nix shell with one conditional recipe instead of `exit 0`, which only ended that line's shell; failures of the Xcode step now propagate - build_secure_storage_deps.sh: stop when cmake, make, meson or ninja fails, before writing the pkg-config file; reconfigure an existing meson build directory instead of failing on it - install_macos_build_tools.sh: put rustup on PATH after `brew install` (resolved with `brew --prefix rustup`), not only if its directory existed before - install_xcode.sh: keep any valid selected Xcode (Xcode_27.1.app, ~/Applications, ...) and only pick one from /Applications when the selection is missing or the Command Line Tools - mwc_ffi_test_service: the invalid-slatepack assertion no longer sits inside its own catch - bm/compare.py: pair measurements by label and host instead of the first row of each file - bm/bench.sh: record failed builds and return make's exit status
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Developer-experience tooling for building Stack Wallet from a checkout with
make, rebased onto current staging (d6ca375, 19 commits, 28 files). It replaces the old draft #1336 and drops what was reviewed negatively there (noflutter createin the build, no patch scripts, noconfigure_*changes, no template pbxproj edits). Everybuild-*target runs the same steps as the matching CI job.Nothing changes in app code or in what the existing CI jobs build; the new workflow is manual only. The only edits to existing files are small:
scripts/prebuild.sh,scripts/app_config/templates/isar_build.sh,scripts/linux/*,README.md,.gitignore,docs/building.md.What it adds
make build-macos: runs the same steps as the CI job (scripts/build_app.sh -p macos -a stack_wallet -s [-d],flutter pub get,scripts/prebuild.sh,flutter build macos --release).PREBUILTS=1(default) passes-d,PREBUILTS=0compiles the native assets from source. Output is the same app as an unmodified checkout:Stack Wallet.app, bundle IDcom.cypherstack.stack_wallet, 319 MB.make build-linux: same flags as the CI job (-dby default,SYSTEM_DEPS=1adds-sfor the system libsecret/jsoncpp packages).make bootstrap-macos(Homebrew; pins Flutter 3.47.4, Rust 1.99.1 via rustup, cbindgen, ...) ornix develop/ direnv (flake.nix,flake.lock,.envrc).make check-reqs,check-reqs-macos,check-sdk-macos,diagnose-env-macos.make bootstrap-xcodeonly checks/selects an installed Xcode.make bootstrap-xcode-downloadis opt-in and downloads a.xipfrom archive.org; it checks the SHA-1 listed by archive.org and Apple's signature (pkgutil --check-signature) and aborts if either fails, strips the quarantine attribute, never runs in CI, and accepts the license / runs first-launch only with-y. Default Xcode 27.1; dnix pins 27.0 for Apple source builds and lock verification, useXCODE_VERSION=27.0for that.make build-windows(Git Bash; same steps as thebuild-windowsjob,WINDOWS_COPY_ASSETS=1for runners without symlinks),make build-android(CI steps; creates a throw-away debug key viaandroid-dev-keywhenandroid/key.propertiesis missing, never for releases),make build-ios(flutter build ios --release --no-codesign).make clean-app(removesbuild/and Pods but keeps the native-asset outputs, next build 53 s instead of 494 s) andmake clean-native.stack-bom.toml+tool/verify_bom.dart+make verify-bom: checks Flutter/Dart/Rust/Go/Xcode and the pinned native plugins against one small file (no packages needed,--updateregenerates the plugin list frompubspec.lock)..github/workflows/make-build.yaml: manual only (workflow_dispatch), runs the make targets on Windows, macOS, Linux (plusverify-bom) and iOS runners. It does not change the existing workflows.make sccache-setup(opt-in; writes~/.cargo/config.tomlonly if absent) andmake cache-stats.bm/benchmark scripts (bm/run_all.sh: cold/warm, prebuilt/from source, sccache on/off, sccache hits recorded) and the MWC FFI integration tests (make test-mwc).docs/building.md: new "Building with make" section.Small fixes in existing scripts
isar_build.shlooked forisar_core_ffiunder a hard-coded$HOME/.pub-cache; it now uses${PUB_CACHE:-$HOME/.pub-cache}.prebuild.shuses#!/usr/bin/env bash(there is no/bin/bashon NixOS).build_app.shis unchanged; the Makefile runs it fromscripts/like the CI jobs do.Verification (one machine each, one run each)
make build-macos, clean checkoutStack Wallet.app319.0 MB, bundle ID unchangedPREBUILTS=0(all native assets from source)nix develop(Flutter 3.47.4 from nixpkgs)make build-linux(nix develop, Rust 1.99.1)bundle/stack_wallet, 291 MBmake build-linux, clean checkoutmake build-macosonmacos-latest,make build-linuxonubuntu-24.04xcodebuild -version= 27.1 (27A9275);xcode-select/license/first-launch (sudo) not runscripts/install_macos_build_tools.shon a Mac with Homebrew (temporaryFLUTTER_DIR)nix develop):make build-linuxwith the default-d(prebuilt native assets), fresh checkoutmake build-linux SYSTEM_DEPS=1(=-d -s, the CI flags)download_xcode.sh -y(incl. xcode-select, license, first launch),make bootstrap-macos,make build-macosStack Wallet.app319.0 MBdart format --set-exit-if-changedon the changed Dart filesmake build-windows(windows-2022),make build-macos(macos-latest),make verify-bom+make build-linux(ubuntu-24.04),make build-iosmake build-macoson the combined branchmake verify-bom--target android), before the last merge, same Makefile codeandroid-dev-key: APKs 183 / 219 / 235 MB (arm / arm64 / x86_64). Without a key it fails at:app:packageReleaseRunner.app205.5 MB, 452 s, device build, no simulatormake clean-appthen rebuildAn unmodified staging also builds on macOS 27.2 without any patches (about 12 min with
-d, 13 min without), so none of the Xcode-27 / deployment-target workarounds of the older branches are needed.Not tested: a physical fresh Mac (the VM test above is Apple Silicon only), a Windows developer machine (only the hosted runner), Android with a real release key / app bundle, iOS simulator and signing. The upstream Actions jobs have not run on this PR; the runner results above come from the manual workflow in my fork (the Linux runner needed a disk-space cleanup step, already in the workflow). The runner results above are from the first 18 commits; the 19th (review fixes: Windows asset copies, Nix bootstrap guard, Linux dependency build errors, rustup PATH, Xcode selection, slatepack test,
bm/scripts) was checked with stubbed fixtures and upstream'stest/linux-release-bundle, not with full platform builds.Things found on the way
prost-build 0.7(viamwc-libp2p-core) ships a generic-Linuxprotocthat NixOS cannot run, andPROTOCexported in the shell does not reach the hook builds (Flutter 3.47.x filters the environment).make build-linuxtherefore writes a git-ignored.cargo/config.tomlwith[env] PROTOC = "<protoc from PATH>"if none exists. The proper fix is influtter_libmwc(let the hook hand cargo aprotocfound onPATH); I tried that once on NixOS and it worked: https://mam.riat.foo/flutter_libmwc_use_path_protoc.patchbuild_app.shonly regeneratespubspec.yamlfrom the template when the file is unchanged, so the-dchoice of an earlier run sticks in a reused checkout; the Makefile deletes the generatedpubspec.yamlfirst.nix develop,dart run flutter_launcher_iconsfailed because the Dart from the nixpkgs Flutter wrapper does not find the Flutter SDK; the flake now setsFLUTTER_ROOT.hooks_runneris 1.5.0 in both.invalid character in Bundle Identifierbecause of the underscore incom.cypherstack.stack_wallet. Not touched here, it would change the app identity.Caching notes (see also
bm/)Hooks run with a filtered environment (Flutter 3.47.x,
hooks_runner1.5.0), so the old env-based approach no longer applies. Measured on macOS, from-source build of all native assets, one run each: 775 s without sccache, 665 s with sccache and an empty cache (-14%), 534 s with a warm cache (-31%). It works through a cargo config file (make sccache-setup). Prebuilts (-d) only cover tor/epic/mwc, about 12 vs. 13 min cold.With the Flutter 3.50 beta (
hooks_runner1.6.4) a plainCARGO_BUILD_RUSTC_WRAPPER=sccachereaches the hooks without a config file. The project does not resolve on 3.50 at the moment (mockingjayneedsanalyzer13-15, we pin ^10.2).Suggestions
Raise Flutter to
^3.47.4(CIflutter-version, docs,pubspec.template.yaml). Samehooks_runneras 3.47.2, nixpkgs only has 3.47.4, and I built with both. I did not touch the CI pins or the constraint in this PR.Not in this PR (follow-ups)
The
flutter_libmwcprotoc change and a per-library dylib install name in the hooks (both become unnecessary if the four plugin pins move to their dnix commits, see my message), dnix for xelis/spark/mwebd, remaining caching experiments, and Flutter 3.50 (a migration of the code-generation stack). A decision is needed on howflake.nixrelates to dnix's own Nix setup.Supersedes #1336; that draft can be closed once this is reviewed.