diff --git a/.envrc b/.envrc new file mode 100644 index 00000000000..3550a30f2de --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake diff --git a/.gitignore b/.gitignore index 31d4a2c5813..f1a5c63a499 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,11 @@ out/ .gradle/ build/ +# Nix / direnv +.direnv/ +result +result-* + # Python cache __pycache__/ diff --git a/flake.lock b/flake.lock new file mode 100644 index 00000000000..7b3d5fba80c --- /dev/null +++ b/flake.lock @@ -0,0 +1,138 @@ +{ + "nodes": { + "android-nixpkgs": { + "inputs": { + "devshell": "devshell", + "flake-utils": "flake-utils", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1778878828, + "narHash": "sha256-bYqGZNxF7RTcbUeAiMkGzT6cOC/PLNSNGwMwZ+ZcBuM=", + "owner": "tadfisher", + "repo": "android-nixpkgs", + "rev": "723e547172f0b3358f7dbf16883cfb9b27c06643", + "type": "github" + }, + "original": { + "owner": "tadfisher", + "repo": "android-nixpkgs", + "type": "github" + } + }, + "devshell": { + "inputs": { + "nixpkgs": [ + "android-nixpkgs", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1768818222, + "narHash": "sha256-460jc0+CZfyaO8+w8JNtlClB2n4ui1RbHfPTLkpwhU8=", + "owner": "numtide", + "repo": "devshell", + "rev": "255a2b1725a20d060f566e4755dbf571bbbb5f76", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "devshell", + "type": "github" + } + }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "lastModified": 1778716662, + "narHash": "sha256-m1Yf0wZ8j1OHjTc2UwHwyQRSnNeSgLJOd7q5Y45hzi4=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "f7c1a2d347e4c52d5fb8d10cb4d94b5884e546fb", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "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": 1778737229, + "narHash": "sha256-6xWoytx8jFW4PF1GjRm/i/53trbpKGfz6zjzQGBr4cI=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "d7a713c0b7e47c908258e71cba7a2d77cc8d71d5", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-25.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-lib": { + "locked": { + "lastModified": 1777168982, + "narHash": "sha256-GOkGPcboWE9BmGCRMLX3worL4EMnsnG8MyKmXNeYuhQ=", + "owner": "nix-community", + "repo": "nixpkgs.lib", + "rev": "f5901329dade4a6ea039af1433fb087bd9c1fe14", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixpkgs.lib", + "type": "github" + } + }, + "root": { + "inputs": { + "android-nixpkgs": "android-nixpkgs", + "flake-parts": "flake-parts", + "nixpkgs": "nixpkgs" + } + }, + "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 00000000000..6f0910815f7 --- /dev/null +++ b/flake.nix @@ -0,0 +1,45 @@ +{ + description = "uchar element x — reproducible dev environment"; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-25.11"; + + flake-parts.url = "github:hercules-ci/flake-parts"; + + android-nixpkgs = { + url = "github:tadfisher/android-nixpkgs"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + + outputs = + { self, flake-parts, ... }@inputs: + flake-parts.lib.mkFlake { inherit inputs; } ( + { ... }: + { + systems = [ + "x86_64-linux" + "aarch64-linux" + "x86_64-darwin" + "aarch64-darwin" + ]; + + perSystem = + { pkgs, system, ... }: + { + _module.args.pkgs = import inputs.nixpkgs { + inherit system; + config.allowUnfree = true; + config.android_sdk.accept_license = true; + }; + + formatter = pkgs.alejandra; + + devShells.default = import ./nix/shell.nix { + inherit pkgs inputs system; + formatter = pkgs.alejandra; + }; + }; + } + ); +} diff --git a/nix/shell.nix b/nix/shell.nix new file mode 100644 index 00000000000..ab08ee374c3 --- /dev/null +++ b/nix/shell.nix @@ -0,0 +1,81 @@ +{ + pkgs, + inputs, + system, + formatter ? pkgs.alejandra, + ... +}: +let + isLinux = pkgs.stdenv.isLinux; + pinnedJDK = pkgs.jdk21_headless; + + androidCustomPackage = inputs.android-nixpkgs.sdk.${system} ( + sdkPkgs: with sdkPkgs; [ + cmdline-tools-latest + platform-tools + build-tools-36-0-0 + platforms-android-36 + emulator + system-images-android-36-google-apis-playstore-x86-64 + ] + ); + + androidEmulator = pkgs.androidenv.emulateApp { + name = "emulator"; + platformVersion = "36"; + abiVersion = "x86_64"; + systemImageType = "google_apis_playstore"; + configOptions = { + "hw.gpu.enabled" = "yes"; + "hw.gpu.mode" = "swiftshader_indirect"; + "hw.keyboard" = "yes"; + }; + }; + + androidEmulatorNoGPU = pkgs.androidenv.emulateApp { + name = "emulator"; + platformVersion = "36"; + abiVersion = "x86_64"; + systemImageType = "google_apis_playstore"; + configOptions = { + "hw.gpu.enabled" = "no"; + "hw.keyboard" = "yes"; + }; + }; +in +pkgs.mkShell { + packages = [ + pinnedJDK + androidCustomPackage + pkgs.ktlint + pkgs.git + pkgs.coreutils + formatter + ] + ++ pkgs.lib.optionals isLinux [ + (pkgs.writeScriptBin "android-emulator" '' + ${androidEmulator}/bin/run-test-emulator + '') + (pkgs.writeScriptBin "android-emulator-no-gpu" '' + ${androidEmulatorNoGPU}/bin/run-test-emulator + '') + ]; + + env = { + ANDROID_HOME = "${androidCustomPackage}/share/android-sdk"; + ANDROID_SDK_ROOT = "${androidCustomPackage}/share/android-sdk"; + JAVA_HOME = pinnedJDK.home; + GRADLE_OPTS = "-Dorg.gradle.project.android.aapt2FromMavenOverride=${androidCustomPackage}/share/android-sdk/build-tools/36.0.0/aapt2"; + }; + + shellHook = '' + echo "---------------------------------------------------------------------------------------------------" + echo " Uchar Element X Android dev shell." + echo " JDK: $(java -version 2>&1 | head -1)" + echo " ANDROID_HOME: $ANDROID_HOME" + ${pkgs.lib.optionalString isLinux '' + echo " Emulator: run 'android-emulator' else 'android-emulator-no-gpu'" + ''} + echo "---------------------------------------------------------------------------------------------------" + ''; +}