himalaya/flake.nix

252 lines
8.8 KiB
Nix

{
description = "CLI to manage emails";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-23.11";
gitignore = {
url = "github:hercules-ci/gitignore.nix";
inputs.nixpkgs.follows = "nixpkgs";
};
fenix = {
url = "github:soywod/fenix";
inputs.nixpkgs.follows = "nixpkgs";
};
naersk = {
url = "github:nix-community/naersk";
inputs.nixpkgs.follows = "nixpkgs";
};
flake-compat = {
url = "github:edolstra/flake-compat";
flake = false;
};
};
outputs = { self, nixpkgs, gitignore, fenix, naersk, ... }:
let
inherit (gitignore.lib) gitignoreSource;
staticRustFlags = [ "-Ctarget-feature=+crt-static" ];
# Map of map matching supported Nix build systems with Rust
# cross target systems.
crossBuildTargets = {
x86_64-linux = {
x86_64-linux = {
rustTarget = "x86_64-unknown-linux-musl";
};
aarch64-linux = rec {
rustTarget = "aarch64-unknown-linux-musl";
runner = pkgs: "${pkgs.qemu}/bin/qemu-aarch64 ./himalaya";
mkPackage = { system, pkgs }: package:
let
inherit (mkPkgsCross system rustTarget) stdenv;
cc = "${stdenv.cc}/bin/${stdenv.cc.targetPrefix}cc";
in
package // {
TARGET_CC = cc;
CARGO_BUILD_RUSTFLAGS = package.CARGO_BUILD_RUSTFLAGS ++ [ "-Clinker=${cc}" ];
};
};
x86_64-windows = {
rustTarget = "x86_64-pc-windows-gnu";
runner = pkgs:
let wine = pkgs.wine.override { wineBuild = "wine64"; };
in "${wine}/bin/wine64 ./himalaya.exe";
mkPackage = { system, pkgs }: package:
let
inherit (pkgs.pkgsCross.mingwW64) stdenv windows;
cc = "${stdenv.cc}/bin/${stdenv.cc.targetPrefix}cc";
in
package // {
depsBuildBuild = [ stdenv.cc windows.pthreads ];
TARGET_CC = cc;
CARGO_BUILD_RUSTFLAGS = package.CARGO_BUILD_RUSTFLAGS ++ [ "-Clinker=${cc}" ];
};
};
};
aarch64-linux = {
aarch64-linux = {
rustTarget = "aarch64-unknown-linux-musl";
};
};
# FIXME: attribute 'sharedLibrary' missing?
# x86_64-windows = {
# x86_64-windows = {
# rustTarget = "x86_64-pc-windows-gnu";
# runner = _: "./himalaya.exe";
# mkPackage = { system, pkgs }: package: package;
# };
# };
x86_64-darwin = {
x86_64-darwin = {
rustTarget = "x86_64-apple-darwin";
mkPackage = { pkgs, ... }: package:
let inherit (pkgs.darwin.apple_sdk.frameworks) AppKit Cocoa;
in package // {
buildInputs = [ Cocoa ];
NIX_LDFLAGS = "-F${AppKit}/Library/Frameworks -framework AppKit";
};
};
# FIXME: infinite recursion in stdenv?!
# aarch64-darwin = {
# rustTarget = "aarch64-apple-darwin";
# override = { system, pkgs }:
# let
# # inherit (mkPkgsCross system "aarch64-darwin") stdenv;
# inherit ((mkPkgsCross system "aarch64-darwin").pkgsStatic) stdenv darwin;
# inherit (darwin.apple_sdk.frameworks) AppKit Cocoa;
# cc = "${stdenv.cc}/bin/${stdenv.cc.targetPrefix}cc";
# in
# {
# buildInputs = [ Cocoa ];
# NIX_LDFLAGS = "-F${AppKit}/Library/Frameworks -framework AppKit -F${Cocoa}/Library/Frameworks -framework Cocoa";
# NIX_CFLAGS_COMPILE = "-F${AppKit}/Library/Frameworks -framework AppKit -F${Cocoa}/Library/Frameworks -framework Cocoa";
# TARGET_CC = cc;
# CARGO_BUILD_RUSTFLAGS = staticRustFlags ++ [ "-Clinker=${cc}" "-lframework=${Cocoa}/Library/Frameworks" ];
# postInstall = mkPostInstall {
# inherit pkgs;
# bin = "${pkgs.qemu}/bin/qemu-aarch64 ./himalaya";
# };
# };
# };
};
aarch64-darwin = {
aarch64-darwin = {
rustTarget = "aarch64-apple-darwin";
mkPackage = { pkgs, ... }: package:
let inherit (pkgs.darwin.apple_sdk.frameworks) AppKit Cocoa;
in package // {
buildInputs = [ Cocoa ];
NIX_LDFLAGS = "-F${AppKit}/Library/Frameworks -framework AppKit";
};
};
};
};
mkToolchain = import ./rust-toolchain.nix fenix;
mkPkgsCross = buildSystem: crossSystem: import nixpkgs {
system = buildSystem;
crossSystem.config = crossSystem;
};
mkPackageArchives = { pkgs, runner ? "./himalaya" }: ''
export WINEPREFIX="$(mktemp -d)"
cd $out/bin
mkdir -p {man,completions}
${runner} man ./man
${runner} completion bash > ./completions/himalaya.bash
${runner} completion elvish > ./completions/himalaya.elvish
${runner} completion fish > ./completions/himalaya.fish
${runner} completion powershell > ./completions/himalaya.powershell
${runner} completion zsh > ./completions/himalaya.zsh
tar -czf himalaya.tgz himalaya* man completions
${pkgs.zip}/bin/zip -r himalaya.zip himalaya* man completions
'';
mkDevShells = buildPlatform:
let
pkgs = import nixpkgs { system = buildPlatform; };
rust-toolchain = mkToolchain.fromFile { system = buildPlatform; };
in
{
default = pkgs.mkShell {
nativeBuildInputs = with pkgs; [ pkg-config ];
buildInputs = with pkgs; [
# Nix
nixd
nixpkgs-fmt
# Rust
rust-toolchain
cargo-watch
# Email env
gnupg
gpgme
msmtp
notmuch
];
};
};
mkPackages = buildPlatform:
let
pkgs = import nixpkgs { system = buildPlatform; };
mkPackage = targetPlatform: crossBuild:
let mkPackage' = crossBuild.mkPackage or (_: p: p);
in mkPackage' { inherit pkgs; system = buildPlatform; } {
name = "himalaya";
src = gitignoreSource ./.;
# overrideMain = _: {
# postInstall = ''
# mkdir -p $out/share/applications/
# cp assets/himalaya.desktop $out/share/applications/
# '';
# };
doCheck = false;
auditable = false;
strictDeps = true;
CARGO_BUILD_TARGET = targetPlatform;
CARGO_BUILD_RUSTFLAGS = staticRustFlags;
};
buildPackage = doPostInstall: targetPlatform: crossBuild:
let
toolchain = mkToolchain.fromTarget {
inherit pkgs buildPlatform;
targetPlatform = crossBuild.rustTarget;
};
rust = naersk.lib.${buildPlatform}.override {
cargo = toolchain;
rustc = toolchain;
};
package = mkPackage targetPlatform crossBuild;
postInstall = pkgs.lib.optionalAttrs doPostInstall {
postInstall = mkPackageArchives {
inherit pkgs;
runner = (crossBuild.runner or (_: null)) pkgs;
};
};
in
rust.buildPackage package // postInstall;
defaultPackage = buildPackage false buildPlatform crossBuildTargets.${buildPlatform}.${buildPlatform};
packages = builtins.mapAttrs (buildPackage false) crossBuildTargets.${buildPlatform};
archives = pkgs.lib.foldlAttrs (p: k: v: p // { "${k}-archives" = buildPackage true k v; }) { } crossBuildTargets.${buildPlatform};
in
{ default = defaultPackage; } // packages // archives;
mkApp = drv:
let exePath = drv.passthru.exePath or "/bin/himalaya";
in
{
type = "app";
program = "${drv}${exePath}";
};
mkApps = buildPlatform:
let
pkgs = import nixpkgs { system = buildPlatform; };
mkApp' = target: package: mkApp self.packages.${buildPlatform}.${target};
in
builtins.mapAttrs mkApp' crossBuildTargets.${buildPlatform};
supportedSystems = builtins.attrNames crossBuildTargets;
mapSupportedSystem = nixpkgs.lib.genAttrs supportedSystems;
in
{
apps = mapSupportedSystem mkApps;
packages = mapSupportedSystem mkPackages;
devShells = mapSupportedSystem mkDevShells;
};
}