Skip to content

Commit

Permalink
proj: add initial Nix flake support
Browse files Browse the repository at this point in the history
The tooling required to work in this repo can be a little bit
challenging to set up (largely as a side effect of supporting multiple
platforms/languages, each with their own tooling requirements).

In an effort to make this easier and more reproducible this commit adds
the start of a Nix flake[0].

Some starting points:

* `nix build .` - builds the platform verifier Rust library in a release
  configuration using stable Rust.
* `nix build .#rustls-platform-verifier-dbg` - same as above, but with
  the "dbg", "base64", and "docsrs" Cargo features enabled.
* `nix develop` - enter a development shell using a nightly rust
  toolchain, Android studio, Android SDK/NDK, Java, and Maven tools for
  building the Android project and using the release tooling.
* `nix develop .#stable` - same as above, but with the stable Rust
  toolchain.
* `nix develop .#msrv` - same as above, but with the project MSRV Rust
  toolchain.

There's also an android-emu output for creating an Android device
emulator that can be used to run unit tests:

```
nix develop
nix build .#android-emu
./result/bin/run-test-emulator&
adb devices
adb logcat
```

```
nix develop
pushd android && ./gradlew connectedAndroidTest
```

Future work:

* The NDK version is presently pinned to a 23.x version to avoid a clang
  libc++ error. This should be resolved so we can use 24.x
* Support for additional platforms. I believe most of this will work on
  other systems/targets but I've only tested on x86_64 so have left out
  additional support for now

[0]: https://zero-to-nix.com/concepts/flakes
  • Loading branch information
cpu committed Apr 27, 2024
1 parent 99d3a0f commit c4b82d6
Show file tree
Hide file tree
Showing 3 changed files with 267 additions and 1 deletion.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,7 @@
# Ignore all generated Maven local repository files and folders
/android-release-support/maven/pom.xml
/android-release-support/maven/rustls/rustls-platform-verifier/**/
/android-release-support/maven/rustls/rustls-platform-verifier/maven-metadata-local.xml
/android-release-support/maven/rustls/rustls-platform-verifier/maven-metadata-local.xml

# Nix
/result
133 changes: 133 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

130 changes: 130 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11";
flake-parts.url = "github:hercules-ci/flake-parts";
rust-overlay.url = "github:oxalica/rust-overlay";
};

outputs = inputs:
inputs.flake-parts.lib.mkFlake { inherit inputs; } {
# TODO(XXX): in theory this flake could support aarch64-linux,
# x86_64-darwin and aarch64-darwin, but it is untested.
systems = [ "x86_64-linux" ];
perSystem = { config, self', pkgs, lib, system, ... }:
let
buildToolsVersion = "30.0.3";
platformVersion = "33";
rustTargets = [ "${system}-android" ];
abi = (lib.systems.elaborate system).linuxArch;

devDeps = with pkgs; [
android-sdk
android-studio
maven
jdk11 # Matched to CI setup-java task's java-version
der-ascii
];

android-comp = pkgs.androidenv.composeAndroidPackages {
buildToolsVersions = [ buildToolsVersion ];
platformVersions = [ platformVersion ];
abiVersions = [ abi ];

# Note: Pinned presently to NDK 23 specifically to workaround an issue
# with the bundled clang missing libc++ in NDK 24. We can't use NDK
# 22, as it's too old for cargo-ndk.
ndkVersion = "23.1.7779620";

systemImageTypes = [ "default" ];

includeNDK = true;
includeEmulator = true;
includeSystemImages = true;
};

# Note: additional flags can be provided to emulator through
# the $NIX_ANDROID_EMULATOR_FLAGS env var.
android-emu = pkgs.androidenv.emulateApp {
name = "emulate-PlatformVerifier";
platformVersion = platformVersion;
abiVersion = abi;
systemImageType = "default";

# Note: Depending on your hardware you may wish to enable or disable
# this option.
enableGPU = false;
};

android-sdk = android-comp.androidsdk;
android-sdk-root = "${android-sdk}/libexec/android-sdk";

verifierCargoToml = builtins.fromTOML
(builtins.readFile ./rustls-platform-verifier/Cargo.toml);
msrv = verifierCargoToml.package.rust-version;

verifierPackage = features:
(pkgs.makeRustPlatform {
cargo = pkgs.rust-bin.stable.latest.minimal;
rustc = pkgs.rust-bin.stable.latest.minimal;
}).buildRustPackage {
inherit (verifierCargoToml.package) name version;
src = ./.;
buildAndTestSubdir = "rustls-platform-verifier";
cargoLock.lockFile = ./Cargo.lock;
buildFeatures = features;
doCheck = false; # Some tests require networking
};

mkDevShell = rustc:
pkgs.mkShell {
ANDROID_HOME = "${android-sdk-root}";
ANDROID_SDK_ROOT = "${android-sdk-root}";
ANDROID_NDK_ROOT = "${android-sdk-root}/ndk-bundle";
JAVA_HOME = "${pkgs.jdk11}";
# Note: It's important to set this so that gradle uses the correct
# aapt2 binary.
GRADLE_OPTS =
"-Dorg.gradle.project.android.aapt2FromMavenOverride=${android-sdk-root}/build-tools/${buildToolsVersion}/aapt2";
shellHook = ''
export RUST_SRC_PATH=${pkgs.rustPlatform.rustLibSrc}
echo 1>&2 "🔒🔍 rustls-platform-verifier"
'';
nativeBuildInputs = devDeps ++ [ rustc ];
};

in {
_module.args.pkgs = import inputs.nixpkgs {
inherit system;
overlays = [ (import inputs.rust-overlay) ];
config = {
# Allow unfree packages and agree to the Android SDK terms of service.
# Review https://developer.android.com/studio/terms before use.
allowUnfree = true;
android_sdk.accept_license = true;
};
};

# Base library.
packages.rustls-platform-verifier = (verifierPackage [ ]);
# Library with debug extras.
packages.rustls-platform-verifier-dbg =
(verifierPackage [ "dbg" "base64" "docsrs" ]);
# Test emulator.
packages.android-emu = android-emu;
packages.default = self'.packages.rustls-platform-verifier;

devShells.nightly = (mkDevShell (pkgs.rust-bin.selectLatestNightlyWith
(toolchain:
toolchain.default.override { targets = rustTargets; })));
devShells.stable = (mkDevShell
(pkgs.rust-bin.stable.latest.default.override {
targets = rustTargets;
}));
devShells.msrv = (mkDevShell
(pkgs.rust-bin.stable.${msrv}.default.override {
targets = rustTargets;
}));
devShells.default = self'.devShells.nightly;
};
};
}

0 comments on commit c4b82d6

Please sign in to comment.