Skip to content
Snippets Groups Projects
flake.nix 7 KiB
Newer Older
{
  description = "The PrivateStorage Mobile application";
  inputs = {
    nixpkgs = {
      url = "github:NixOS/nixpkgs?ref=nixos-22.05";
    };
    flake-utils.url = "github:numtide/flake-utils";
    pypi-deps-db = {
      flake = false;
      url = "github:DavHau/pypi-deps-db";
    };
    mach-nix-flake = {
      flake = true;
      url = "github:DavHau/mach-nix";
      inputs = {
        nixpkgs.follows = "nixpkgs";
        flake-utils.follows = "flake-utils";
        pypi-deps-db.follows = "pypi-deps-db";
    buildozerSrc = {
      flake = false;
      url = "github:PrivateStorageio/buildozer?ref=build-without-installing";
    };
    pythonForAndroidSrc = {
      flake = false;
      url = "github:PrivateStorageio/python-for-android?ref=work-on-nixos";
    };
  outputs = { self, nixpkgs, flake-utils, mach-nix-flake, buildozerSrc, pythonForAndroidSrc, ... }:
    flake-utils.lib.eachSystem [
      "x86_64-linux"
    ] (system: let

      mach-nix = mach-nix-flake.lib.${system};
Jean-Paul Calderone's avatar
Jean-Paul Calderone committed
      pkgs = import nixpkgs {
        inherit system;
        config = {
          allowUnfree = true;
          android_sdk.accept_license = true;
        };
Jean-Paul Calderone's avatar
Jean-Paul Calderone committed
      };
      python-for-android = mach-nix.buildPythonPackage {
        src = pythonForAndroidSrc;
        requirementsExtra = ''
        sh>=1.10
        '';
      };
      buildozer = mach-nix.buildPythonPackage {
        src = buildozerSrc;
        packagesExtra = [ ];
      };

      kivy-env = mach-nix.mkPython {
        python = "python39";
        requirements = ''
          kivy
          Pillow
          cython
        '';
        packagesExtra = [ python-for-android buildozer ];

      # THESE MUST AGREE WITH app/app/build.gradle
      #
      # If they do not you will get failures that look something like:

      # FAILURE: Build failed with an exception.
      #
      # * What went wrong:
      # Could not determine the dependencies of task ':app:compileReleaseJavaWithJavac'.
      # > Failed to install the following SDK components:
      #       platforms;android-32 Android SDK Platform 32
      #   The SDK directory is not writable (/nix/store/46214a16f22rd7q8vkrhsa907ra0405l-androidsdk/libexec/android-sdk)

      platformVersion = "31";
      buildToolsVersion = "31.0.0";
      # Check out pkgs/development/mobile/androidenv/repo.json for
      # nixpkgs-supported versions.
      ndkVersion = "23.0.7123448-rc1";
      androidComposition = pkgs.callPackage ./android.nix {
        inherit cmakeVersion buildToolsVersion platformVersion ndkVersion;
      getBuildInputs = getInputs: xs: builtins.foldl' (accum: drv: (getInputs drv) ++ accum) [] xs;
      # Make sure gradle uses the aapt2 from our Android SDK.  Otherwise it
      # downloads one from the internet that doesn't work because it
      # specifies an interpreter (ld.so) that nothing has ensured will
      # exist.
      #
      # Without this you get a stack of build errors that look a bit like:
      #
      # Execution failed for task ':app:processDebugResources'.
      # > Could not resolve all files for configuration ':app:debugRuntimeClasspath'.
      #    > Failed to transform appcompat-1.3.0.aar (androidx.appcompat:appcompat:1.3.0) to match attributes {artifactType=android-compiled-dependencies-resources, org.gradle.category=library, org.gradle.dependency.bundling=external, org.gradle.libraryelements=aar, org.gradle.status=release, org.gradle.usage=java-runtime}.
      #       > Execution failed for AarResourcesCompilerTransform: /home/exarkun/.gradle/caches/transforms-3/f5908003b5fc10a9cf0fd543db10ae32/transformed/appcompat-1.3.0.
      #          > AAPT2 aapt2-7.2.1-7984345-linux Daemon #1: Daemon startup failed
      #            This should not happen under normal circumstances, please file an issue if it does.
      ANDROIDSDK = "${androidComposition.androidsdk}/libexec/android-sdk";
      gradle-wrapper = pkgs.writeShellApplication {
        name = "gradle";
        text = ''
        ${pkgs.gradle}/bin/gradle -Pandroid.aapt2FromMavenOverride=${ANDROIDSDK}/build-tools/${buildToolsVersion}/aapt2 "$@"
      packages.apk = pkgs.androidenv.buildApp {
        name = "PrivateStorage Mobile";
        src = ./app;
        release = false;

        platformVersions = [ platformVersion ];
      apps.emulate = {
        type = "app";
        program = let
          emulator = pkgs.androidenv.emulateApp {
            name = "PrivateStorage Mobile";
            inherit platformVersion;
            abiVersion = "x86_64";
            systemImageType = "default";
            package = "MyApp";
            activity = "MainActivity";
          };
        in
          "${emulator}/bin/run-test-emulator";
      };
      devShells.gradle = pkgs.mkShell rec {
        name = "nix-native";
        version = "2022.11.09";

        inherit ANDROIDSDK;
        ANDROIDNDK = "${ANDROIDSDK}/ndk-bundle";

        ANDROID_SDK_ROOT = ANDROIDSDK;
        ANDROID_NDK_ROOT = ANDROIDNDK;

        # Deprecated but ... :shrug:
        ANDROID_HOME = ANDROIDSDK;

        buildInputs = with pkgs; [
          ant
          android-studio
          android-tools
          python39
        ];

        shellHook = ''
        # Tell the tools a third time where the SDK and NDK are to be found.
        cat >app/local.properties <<EOF
        # THIS FILE IS AUTOMATICALLY GENERATED
        # DO NOT EDIT
        # YOUR CHANGES WILL BE DESTROYED

        sdk.dir=${ANDROIDSDK}
      };

      devShells.default = self.devShells.${system}.gradle;

      # https://github.com/NixOS/nixpkgs/blob/master/doc/languages-frameworks/android.section.md
      # is a good reference for this stuff.
      devShells.kivy = pkgs.mkShell rec {
        # The docs talk about ANDROID_SDK_ROOT but apparently it has been
        # renamed yet again.
        ANDROIDSDK = "${androidComposition.androidsdk}/libexec/android-sdk";
        ANDROIDNDK = "${ANDROIDSDK}/ndk-bundle";

        shellHook = ''
        export PATH="$(echo "$ANDROIDSDK/cmake/${cmakeVersion}".*/bin):$PATH"
        '';

        buildInputs = with pkgs; [
          android-studio

          # Kivy and python-for-android depend on:
Jean-Paul Calderone's avatar
Jean-Paul Calderone committed
          # https://github.com/kivy/python-for-android/blob/v2020.04.29/doc/source/troubleshooting.rst#errors-related-to-java-version

          # python-for-android recipes all want to download and unpack their
          # own sources!  aaaaaa
          unzip
        ] ++

        # Also we need build dependencies for all of the things it is going to
        # build!
        (getBuildInputs (drv: drv.buildInputs) [ openssl libffi python39 ]);

        nativeBuildInputs =
          with pkgs; getBuildInputs (drv: drv.nativeBuildInputs) [ openssl libffi python39 ];