diff --git a/flake.lock b/flake.lock new file mode 100644 index 00000000..cfb7a8b6 --- /dev/null +++ b/flake.lock @@ -0,0 +1,82 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1777268161, + "narHash": "sha256-bxrdOn8SCOv8tN4JbTF/TXq7kjo9ag4M+C8yzzIRYbE=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "1c3fe55ad329cbcb28471bb30f05c9827f724c76", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs", + "rust-overlay": "rust-overlay" + } + }, + "rust-overlay": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1777605393, + "narHash": "sha256-Hjp0VOOHgHcTrX23iVvnfAudPcuCmfkfpQNFwv2v/ks=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "ff88db34cfa486fc4964a6991cab1678d82eee8c", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 00000000..e04a1ff8 --- /dev/null +++ b/flake.nix @@ -0,0 +1,43 @@ +{ + description = "WalletKit development shells"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + flake-utils.url = "github:numtide/flake-utils"; + rust-overlay.url = "github:oxalica/rust-overlay"; + rust-overlay.inputs.nixpkgs.follows = "nixpkgs"; + }; + + outputs = { nixpkgs, flake-utils, rust-overlay, ... }: + flake-utils.lib.eachSystem [ + "x86_64-linux" + "aarch64-darwin" + "x86_64-darwin" + ] (system: + let + overlays = [ (import rust-overlay) ]; + pkgs = import nixpkgs { + inherit system overlays; + config = { + allowUnfree = true; + android_sdk.accept_license = true; + }; + }; + + rustToolchain = pkgs.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml; + in + { + devShells = { + default = pkgs.mkShell { + packages = [ + rustToolchain + pkgs.curl + pkgs.git + ]; + }; + + android = import ./nix/android.nix { inherit pkgs; }; + wasm = import ./nix/wasm.nix { inherit pkgs; }; + }; + }); +} diff --git a/nix/android.nix b/nix/android.nix new file mode 100644 index 00000000..abd327ad --- /dev/null +++ b/nix/android.nix @@ -0,0 +1,74 @@ +{ pkgs }: +let + androidApiLevel = "23"; + androidPackages = pkgs.androidenv.composeAndroidPackages { + platformVersions = [ androidApiLevel ]; + includeNDK = true; + ndkVersion = "27.2.12479018"; + }; + androidNdkPackage = androidPackages.ndk-bundle; + androidNdkHome = "${androidNdkPackage}/libexec/android-sdk/ndk-bundle"; + androidToolchainPlatform = if pkgs.stdenv.isDarwin then "darwin-x86_64" else "linux-x86_64"; + androidToolchainBin = "${androidNdkHome}/toolchains/llvm/prebuilt/${androidToolchainPlatform}/bin"; + + androidClang = "${androidToolchainBin}/aarch64-linux-android${androidApiLevel}-clang"; + androidClangxx = "${androidToolchainBin}/aarch64-linux-android${androidApiLevel}-clang++"; + androidI686Clang = "${androidToolchainBin}/i686-linux-android${androidApiLevel}-clang"; + androidI686Clangxx = "${androidToolchainBin}/i686-linux-android${androidApiLevel}-clang++"; + androidArmv7Clang = "${androidToolchainBin}/armv7a-linux-androideabi${androidApiLevel}-clang"; + androidArmv7Clangxx = "${androidToolchainBin}/armv7a-linux-androideabi${androidApiLevel}-clang++"; + androidX8664Clang = "${androidToolchainBin}/x86_64-linux-android${androidApiLevel}-clang"; + androidX8664Clangxx = "${androidToolchainBin}/x86_64-linux-android${androidApiLevel}-clang++"; + androidRustflags = "-Clink-arg=-z -Clink-arg=max-page-size=16384 -Clink-arg=-z -Clink-arg=common-page-size=4096"; + + rustToolchain = pkgs.rust-bin.fromRustupToolchainFile ../rust-toolchain.toml; +in +pkgs.mkShell { + packages = [ + rustToolchain + androidNdkPackage + pkgs.curl + pkgs.git + ]; + + ANDROID_API_LEVEL = androidApiLevel; + ANDROID_NDK_HOME = androidNdkHome; + ANDROID_NDK_ROOT = androidNdkHome; + NDK_HOME = androidNdkHome; + + CC_aarch64_linux_android = androidClang; + CXX_aarch64_linux_android = androidClangxx; + AR_aarch64_linux_android = "${androidToolchainBin}/llvm-ar"; + RANLIB_aarch64_linux_android = "${androidToolchainBin}/llvm-ranlib"; + CARGO_TARGET_AARCH64_LINUX_ANDROID_LINKER = androidClang; + CARGO_TARGET_AARCH64_LINUX_ANDROID_RUSTFLAGS = androidRustflags; + + CC_i686_linux_android = androidI686Clang; + CXX_i686_linux_android = androidI686Clangxx; + AR_i686_linux_android = "${androidToolchainBin}/llvm-ar"; + RANLIB_i686_linux_android = "${androidToolchainBin}/llvm-ranlib"; + CARGO_TARGET_I686_LINUX_ANDROID_LINKER = androidI686Clang; + CARGO_TARGET_I686_LINUX_ANDROID_RUSTFLAGS = androidRustflags; + + CC_armv7_linux_androideabi = androidArmv7Clang; + CXX_armv7_linux_androideabi = androidArmv7Clangxx; + AR_armv7_linux_androideabi = "${androidToolchainBin}/llvm-ar"; + RANLIB_armv7_linux_androideabi = "${androidToolchainBin}/llvm-ranlib"; + CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_LINKER = androidArmv7Clang; + CARGO_TARGET_ARMV7_LINUX_ANDROIDEABI_RUSTFLAGS = androidRustflags; + + CC_x86_64_linux_android = androidX8664Clang; + CXX_x86_64_linux_android = androidX8664Clangxx; + AR_x86_64_linux_android = "${androidToolchainBin}/llvm-ar"; + RANLIB_x86_64_linux_android = "${androidToolchainBin}/llvm-ranlib"; + CARGO_TARGET_X86_64_LINUX_ANDROID_LINKER = androidX8664Clang; + CARGO_TARGET_X86_64_LINUX_ANDROID_RUSTFLAGS = androidRustflags; + + shellHook = '' + echo "WalletKit Android dev shell" + echo " targets: aarch64-linux-android, armv7-linux-androideabi, i686-linux-android, x86_64-linux-android (API $ANDROID_API_LEVEL)" + echo " ndk: $ANDROID_NDK_HOME" + echo "" + echo "Build with: cargo build -p walletkit --release --target aarch64-linux-android --features compress-zkeys,v3" + ''; +} diff --git a/nix/build-android.sh b/nix/build-android.sh new file mode 100755 index 00000000..4f34f909 --- /dev/null +++ b/nix/build-android.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash +set -euo pipefail + +cd "$(dirname "${BASH_SOURCE[0]}")/.." + +readonly TARGETS=( + "aarch64-linux-android" + "armv7-linux-androideabi" + "x86_64-linux-android" + "i686-linux-android" +) + +usage() { + cat < + +Targets: +$(printf ' %s\n' "${TARGETS[@]}") + +EOF +} + +TARGET="" + +while [[ $# -gt 0 ]]; do + case "$1" in + --target | -t) + if [[ $# -lt 2 ]]; then + echo "error: --target requires a value" >&2 + usage >&2 + exit 1 + fi + TARGET="$2" + shift 2 + ;; + --help | -h) + usage + exit 0 + ;; + *) + echo "error: unknown argument: $1" >&2 + usage >&2 + exit 1 + ;; + esac +done + +if [[ -z "${TARGET}" ]]; then + echo "error: --target is required" >&2 + usage >&2 + exit 1 +fi + +valid_target=false +for candidate in "${TARGETS[@]}"; do + if [[ "${TARGET}" == "${candidate}" ]]; then + valid_target=true + break + fi +done + +if [[ "${valid_target}" != true ]]; then + echo "error: unsupported target: ${TARGET}" >&2 + usage >&2 + exit 1 +fi + +exec nix develop .#android --command cargo build \ + -p walletkit \ + --release \ + --target "${TARGET}" \ + --features compress-zkeys,v3 diff --git a/nix/build-wasm.sh b/nix/build-wasm.sh new file mode 100755 index 00000000..f53b7542 --- /dev/null +++ b/nix/build-wasm.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +set -euo pipefail + +cd "$(dirname "${BASH_SOURCE[0]}")/.." + +exec nix develop .#wasm --command cargo build \ + -p walletkit \ + --release \ + --target wasm32-unknown-unknown \ + "$@" diff --git a/nix/wasm.nix b/nix/wasm.nix new file mode 100644 index 00000000..5c88d893 --- /dev/null +++ b/nix/wasm.nix @@ -0,0 +1,26 @@ +{ pkgs }: +let + rustToolchain = pkgs.rust-bin.fromRustupToolchainFile ../rust-toolchain.toml; + llvm = pkgs.llvmPackages; +in +pkgs.mkShell { + packages = [ + rustToolchain + llvm.clang-unwrapped + llvm.bintools-unwrapped + pkgs.curl + pkgs.git + ]; + + # Use unwrapped clang: cc-wrapper injects host hardening flags that are invalid for wasm. + CC_wasm32_unknown_unknown = "${llvm.clang-unwrapped}/bin/clang"; + AR_wasm32_unknown_unknown = "${llvm.bintools-unwrapped}/bin/llvm-ar"; + + shellHook = '' + echo "WalletKit wasm dev shell" + echo " target: wasm32-unknown-unknown" + echo " clang: $CC_wasm32_unknown_unknown" + echo "" + echo "Build with: cargo build -p walletkit --target wasm32-unknown-unknown" + ''; +}