diff --git a/apps/amm/MACOS.md b/apps/amm/MACOS.md new file mode 100644 index 0000000..27b585c --- /dev/null +++ b/apps/amm/MACOS.md @@ -0,0 +1,95 @@ +# AMM UI on macOS + +The AMM UI supports both Apple Silicon and Intel Macs through the Nix flake. +The project packages its QML wallet and AMM client libraries with relative +macOS loader paths, so a normal `nix run .` does not need `DYLD_LIBRARY_PATH`. + +## One-time prerequisites + +Install Nix in multi-user mode, make sure its daemon is running, and enable +flakes: + +```sh +mkdir -p ~/.config/nix +printf '%s\n' 'experimental-features = nix-command flakes' >> ~/.config/nix/nix.conf +nix --version +``` + +The build uses RISC Zero's Metal kernel build on Darwin. Apple Command Line +Tools alone do not provide the `metal` and `metallib` compilers. Install the +full Xcode application, select it, accept its licence, and install the Metal +Toolchain component when Xcode asks for it: + +```sh +sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer +sudo xcodebuild -license accept +xcodebuild -downloadComponent MetalToolchain +xcrun --sdk macosx --find metal +xcrun --sdk macosx --find metallib +``` + +The last two commands must print paths. Do not use `RISC0_SKIP_BUILD_KERNELS=1` +as a replacement: the pinned RISC Zero version still invokes the Metal build +for this dependency graph. + +Leave at least 40 GiB free before the first build. Qt, Rust and Nix closures +are large; later runs reuse the Nix store cache. + +## Build and run + +From this directory: + +```sh +nix build . +nix run . +``` + +The first start opens the AMM UI without a wallet. Select **Connect** to create +or open the wallet stored under `~/.lee/wallet/`. + +## Recovery + +### `nix: command not found` or no `/nix` volume + +Open a new terminal after installing Nix. If the Nix volume is not mounted or +the daemon is not available, repair the Nix installation using the installer +for the installed Nix version. Check the actual service state before trying to +bootstrap it again: + +```sh +test -x /nix/var/nix/profiles/default/bin/nix +sudo launchctl print system/org.nixos.nix-daemon +``` + +`launchctl bootstrap` can report an I/O error when the service is already in +an inconsistent state; it is not proof that the daemon is stopped. + +### `xcrun: unable to find utility "metal"` + +The active developer directory points at Command Line Tools or lacks the Metal +Toolchain component. Repeat the Xcode selection and Metal verification steps +above. This is an Apple-host prerequisite and cannot be packaged inside the +flake. + +### The first build runs out of space + +Remove only disposable build outputs, then collect dead Nix store paths: + +```sh +rm -rf /private/tmp/amm-pr210-build +nix-store --gc +``` + +Do not remove `/nix/store` directly. + +### A local flake lock error mentions an unlocked `amm_client` input + +The committed `flake.lock` includes a hash for the repository-local client +input. Restore that file if a local experiment replaced it, then retry: + +```sh +git restore flake.lock +nix flake metadata --no-write-lock-file +``` + +Run these commands from `apps/amm`. diff --git a/apps/amm/README.md b/apps/amm/README.md index 73f15c9..16033ca 100644 --- a/apps/amm/README.md +++ b/apps/amm/README.md @@ -50,6 +50,9 @@ nix profile install 'github:logos-co/logos-package-manager#cli' This makes `lgpm` available as a global command. +For macOS prerequisites, the Metal toolchain requirement, and common Nix +recovery steps, see [macOS setup](MACOS.md). + ## Running the UI standalone Start the UI with: diff --git a/apps/amm/flake.lock b/apps/amm/flake.lock index f5272d3..ee067f5 100644 --- a/apps/amm/flake.lock +++ b/apps/amm/flake.lock @@ -6,6 +6,8 @@ "nixpkgs": "nixpkgs" }, "locked": { + "lastModified": 1784149231, + "narHash": "sha256-C2Z0t4FNq0tLlFosZ6/HNYoq2jqSkEJeytObS3I/MPA=", "path": "../..", "type": "path" }, @@ -26901,6 +26903,8 @@ "shared_wallet": { "flake": false, "locked": { + "lastModified": 1784149231, + "narHash": "sha256-yhF0x6BrOn3IvffBq+jjnwfDWKK0NrMV7iFsHvCvqc8=", "path": "../shared/wallet", "type": "path" }, diff --git a/apps/amm/flake.nix b/apps/amm/flake.nix index c8eb4e0..c1ad4d0 100644 --- a/apps/amm/flake.nix +++ b/apps/amm/flake.nix @@ -45,6 +45,19 @@ mkdir -p "$walletQmlInstallDir" cp -r "$walletQmlDir/." "$walletQmlInstallDir/" test -f "$walletQmlInstallDir/qmldir" + + # The standalone plugin directory only copies directories below lib/. + # Ship the Rust client in one of those directories and teach the + # backend plugin to resolve it relative to its installed location. + # This is deliberately relative so both the development Nix build and + # the portable LGX package work without DYLD_LIBRARY_PATH. + if [ -f "$out/lib/libamm_client.dylib" ]; then + runtimeLibDir="$out/lib/amm_ui_runtime" + mkdir -p "$runtimeLibDir" + cp "$out/lib/libamm_client.dylib" "$runtimeLibDir/" + install_name_tool -add_rpath "@loader_path/amm_ui_runtime" \ + "$out/lib/amm_ui_plugin.dylib" + fi ''; }; } diff --git a/apps/shared/wallet/CMakeLists.txt b/apps/shared/wallet/CMakeLists.txt index 37f1663..f6fd192 100644 --- a/apps/shared/wallet/CMakeLists.txt +++ b/apps/shared/wallet/CMakeLists.txt @@ -106,11 +106,21 @@ if(LOGOS_WALLET_BUILD_QML) Qt6::Quick Qt6::QuickControls2 ) + # ELF loaders resolve $ORIGIN, while dyld uses @loader_path. The QML + # plugin and its implementation library are installed side by side, so + # use the native spelling on each platform rather than requiring callers + # to set DYLD_LIBRARY_PATH on macOS. + if(APPLE) + set(wallet_qml_install_rpath "@loader_path") + else() + set(wallet_qml_install_rpath "$ORIGIN") + endif() + set_target_properties(logos_wallet_qml logos_wallet_qmlplugin PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${wallet_qml_output_dir}" RUNTIME_OUTPUT_DIRECTORY "${wallet_qml_output_dir}" BUILD_WITH_INSTALL_RPATH ON - INSTALL_RPATH "$ORIGIN" + INSTALL_RPATH "${wallet_qml_install_rpath}" ) set(wallet_qml_install_dir "lib/qml/Logos/Wallet")