crabidy/flake.nix

150 lines
5.3 KiB
Nix

{
description = "crabidy a client/server music player";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
crane.url = "github:ipetkov/crane";
fenix = {
url = "github:nix-community/fenix";
inputs.nixpkgs.follows = "nixpkgs";
};
flake-utils.url = "github:numtide/flake-utils";
};
outputs =
{
self,
nixpkgs,
crane,
fenix,
flake-utils,
}:
flake-utils.lib.eachDefaultSystem (
system:
let
pkgs = import nixpkgs { inherit system; };
lib = pkgs.lib;
fenixPkgs = fenix.packages.${system};
# Source that keeps the .proto files crabidy-core/build.rs compiles —
# crane's default cargo-source cleaning would drop them.
src = lib.cleanSourceWith {
src = ./.;
name = "crabidy-source";
filter =
path: type:
(builtins.match ".*\\.proto$" path != null) || (crane.mkLib pkgs).filterCargoSources path type;
};
# Only the real binary crates; never build cbd-web (a wasm crate) for a
# host or aarch64 target. Headless: --no-default-features drops the
# embedded web UI (its own wasm-bundle derivation is future work).
workspaceBins = "-p crabidy-server -p cbd -p cbd-tui";
# --- Native toolchain / build (for `nix profile install` on x86_64,
# aarch64, etc.) ---
craneLib = (crane.mkLib pkgs).overrideToolchain (_: fenixPkgs.stable.toolchain);
nativeArgs = {
inherit src;
strictDeps = true;
cargoExtraArgs = "--locked --no-default-features ${workspaceBins}";
# protoc + pkg-config are build-host tools (run during the build);
# with strictDeps they must be nativeBuildInputs or alsa-sys cannot
# find pkg-config. alsa-lib is the actual linked library.
nativeBuildInputs = [
pkgs.protobuf
pkgs.pkg-config
];
buildInputs = [ pkgs.alsa-lib ];
# audio-player links libasound; yt-dlp for /youtube stays a runtime
# dependency, not wired here.
};
nativeDeps = craneLib.buildDepsOnly nativeArgs;
crabidy = craneLib.buildPackage (
nativeArgs
// {
cargoArtifacts = nativeDeps;
doCheck = false; # tests need a config/network; `nix flake check` can run them later
}
);
# --- Cross toolchain / build: static aarch64 musl (a portable binary
# that runs on any aarch64 Linux, incl. a Raspberry Pi) ---
muslTarget = "aarch64-unknown-linux-musl";
crossPkgs = pkgs.pkgsCross.aarch64-multiplatform-musl;
crossCc = "${crossPkgs.stdenv.cc}/bin/${crossPkgs.stdenv.cc.targetPrefix}cc";
# Static alsa-lib for the target, linked into the binary.
crossAlsa = crossPkgs.pkgsStatic.alsa-lib;
crossToolchain = fenixPkgs.combine [
fenixPkgs.stable.rustc
fenixPkgs.stable.cargo
fenixPkgs.targets.${muslTarget}.stable.rust-std
];
craneLibCross = (crane.mkLib pkgs).overrideToolchain (_: crossToolchain);
crossEnvTarget = "AARCH64_UNKNOWN_LINUX_MUSL";
crossArgs = {
inherit src;
strictDeps = true;
cargoExtraArgs = "--locked --no-default-features -p crabidy-server";
CARGO_BUILD_TARGET = muslTarget;
# Build scripts / proc-macros compile for the build host; deps for the
# target use the cross toolchain. protoc + pkg-config are host tools.
nativeBuildInputs = [
pkgs.protobuf
pkgs.pkg-config
];
buildInputs = [ crossAlsa ];
depsBuildBuild = [ crossPkgs.stdenv.cc ];
# cc-rs (aws-lc-sys, rustls's crypto backend) needs the cross C
# compiler; the linker is the same cross cc. Static CRT + -static so
# the binary has no interpreter and runs standalone.
"CC_aarch64_unknown_linux_musl" = crossCc;
"CARGO_TARGET_${crossEnvTarget}_LINKER" = crossCc;
"CARGO_TARGET_${crossEnvTarget}_RUSTFLAGS" = "-C target-feature=+crt-static -C link-arg=-static";
# pkg-config resolves the target's static alsa-lib for alsa-sys.
PKG_CONFIG_ALLOW_CROSS = "1";
PKG_CONFIG_PATH_aarch64_unknown_linux_musl = "${crossAlsa.dev}/lib/pkgconfig";
};
crossDeps = craneLibCross.buildDepsOnly crossArgs;
crabidy-server-aarch64 = craneLibCross.buildPackage (
crossArgs
// {
cargoArtifacts = crossDeps;
doCheck = false; # cannot run aarch64 tests on an x86_64 builder
}
);
in
{
packages = {
default = crabidy;
inherit crabidy crabidy-server-aarch64;
};
apps = {
cbd = flake-utils.lib.mkApp {
drv = crabidy;
name = "cbd";
};
cbd-tui = flake-utils.lib.mkApp {
drv = crabidy;
name = "cbd-tui";
};
crabidy-server = flake-utils.lib.mkApp {
drv = crabidy;
name = "crabidy-server";
};
default = flake-utils.lib.mkApp {
drv = crabidy;
name = "cbd";
};
};
}
);
}