aboutsummaryrefslogtreecommitdiff
path: root/flake.nix
diff options
context:
space:
mode:
authorAlex Auvolat <lx@deuxfleurs.fr>2025-01-14 18:47:39 +0100
committerAlex Auvolat <lx@deuxfleurs.fr>2025-01-14 18:47:39 +0100
commit40c2891ccd144b08b06a2d0036317e533c982927 (patch)
tree2b3e90d85f9b6e88e724d40d525a212dce1093d9 /flake.nix
parent39ac034de55c7040b61a08ecb95c58afa983501c (diff)
downloadgarage-40c2891ccd144b08b06a2d0036317e533c982927.tar.gz
garage-40c2891ccd144b08b06a2d0036317e533c982927.zip
wip use naersk but doesn't split build in many derivationsnaersk
Diffstat (limited to 'flake.nix')
-rw-r--r--flake.nix221
1 files changed, 142 insertions, 79 deletions
diff --git a/flake.nix b/flake.nix
index b1cb7dbb..014898a3 100644
--- a/flake.nix
+++ b/flake.nix
@@ -2,92 +2,155 @@
description =
"Garage, an S3-compatible distributed object store for self-hosted deployments";
+ # Cross-compilation logic from here:
+ # https://mediocregopher.com/posts/x-compiling-rust-with-nix
+ # Thank you so much!!
+
# Nixpkgs 24.11 as of 2025-01-12 has rustc v1.82
inputs.nixpkgs.url =
"github:NixOS/nixpkgs/7c4869c47090dd7f9f1bdfb49a22aea026996815";
inputs.flake-compat.url = "github:nix-community/flake-compat";
- inputs.cargo2nix = {
- # As of 2022-10-18: two small patches over unstable branch, one for clippy and one to fix feature detection
- #url = "github:Alexis211/cargo2nix/a7a61179b66054904ef6a195d8da736eaaa06c36";
-
- # As of 2023-04-25:
- # - my two patches were merged into unstable (one for clippy and one to "fix" feature detection)
- # - rustc v1.66
- # url = "github:cargo2nix/cargo2nix/8fb57a670f7993bfc24099c33eb9c5abb51f29a2";
-
- # Mainline cargo2nix as of of 2025-01-12 (branch release-0.11.0)
- url = "github:cargo2nix/cargo2nix/ae19a9e1f8f0880c088ea155ab66cee1fa001f59";
-
- # Rust overlay as of 2025-01-12
- inputs.rust-overlay.url =
- "github:oxalica/rust-overlay/162ab0edc2936508470199b2e8e6c444a2535019";
-
- inputs.nixpkgs.follows = "nixpkgs";
- inputs.flake-compat.follows = "flake-compat";
- };
-
- inputs.flake-utils.follows = "cargo2nix/flake-utils";
-
- outputs = { self, nixpkgs, cargo2nix, flake-utils, ... }:
- let
- git_version = self.lastModifiedDate;
- compile = import ./nix/compile.nix;
- in
- flake-utils.lib.eachDefaultSystem (system:
- let
- pkgs = nixpkgs.legacyPackages.${system};
- in
- {
- packages =
- let
- packageFor = target: (compile {
- inherit system git_version target;
- pkgsSrc = nixpkgs;
- cargo2nixOverlay = cargo2nix.overlays.default;
- release = true;
- }).workspace.garage { compileMode = "build"; };
- in
- {
- # default = native release build
- default = packageFor null;
- # other = cross-compiled, statically-linked builds
- amd64 = packageFor "x86_64-unknown-linux-musl";
- i386 = packageFor "i686-unknown-linux-musl";
- arm64 = packageFor "aarch64-unknown-linux-musl";
- arm = packageFor "armv6l-unknown-linux-musl";
+ inputs.fenix.url = "github:nix-community/fenix";
+ inputs.naersk.url = "github:nix-community/naersk/master";
+
+ outputs = { self, nixpkgs, fenix, naersk, ... }:
+ let
+ buildTargets = {
+ "x86_64-linux" = {
+ crossSystemConfig = "x86_64-unknown-linux-musl";
+ rustTarget = "x86_64-unknown-linux-musl";
+ };
+
+ "i686-linux" = {
+ crossSystemConfig = "i686-unknown-linux-musl";
+ rustTarget = "i686-unknown-linux-musl";
+ };
+
+ "aarch64-linux" = {
+ crossSystemConfig = "aarch64-unknown-linux-musl";
+ rustTarget = "aarch64-unknown-linux-musl";
+ };
+
+ # Old Raspberry Pi's
+ "armv6l-linux" = {
+ crossSystemConfig = "armv6l-unknown-linux-musleabihf";
+ rustTarget = "arm-unknown-linux-musleabihf";
+ };
+ };
+
+ # eachSystem [system] (system: ...)
+ #
+ # Returns an attrset with a key for every system in the given array, with
+ # the key's value being the result of calling the callback with that key.
+ eachSystem = supportedSystems: callback: builtins.foldl'
+ (overall: system: overall // { ${system} = callback system; })
+ {}
+ supportedSystems;
+
+ # eachCrossSystem [system] (buildSystem: targetSystem: ...)
+ #
+ # Returns an attrset with a key "$buildSystem.cross-$targetSystem" for
+ # every combination of the elements of the array of system strings. The
+ # value of the attrs will be the result of calling the callback with each
+ # combination.
+ #
+ # There will also be keys "$system.default", which are aliases of
+ # "$system.cross-$system" for every system.
+ #
+ eachCrossSystem = supportedSystems: callback:
+ eachSystem supportedSystems (buildSystem: builtins.foldl'
+ (inner: targetSystem: inner // {
+ "cross-${targetSystem}" = callback buildSystem targetSystem;
+ })
+ { default = callback buildSystem buildSystem; }
+ supportedSystems
+ );
+
+ mkPkgs = buildSystem: targetSystem: import nixpkgs ({
+ system = buildSystem;
+ } // (if targetSystem == null then {} else {
+ # The nixpkgs cache doesn't have any packages where cross-compiling has
+ # been enabled, even if the target platform is actually the same as the
+ # build platform (and therefore it's not really cross-compiling). So we
+ # only set up the cross-compiling config if the target platform is
+ # different.
+ crossSystem.config = buildTargets.${targetSystem}.crossSystemConfig;
+ }));
+
+ in {
+ packages = eachCrossSystem
+ (builtins.attrNames buildTargets)
+ (buildSystem: targetSystem: let
+ pkgs = mkPkgs buildSystem null;
+ pkgsCross = mkPkgs buildSystem targetSystem;
+ rustTarget = buildTargets.${targetSystem}.rustTarget;
+
+ # TODO I'd prefer to use the toolchain file
+ # https://github.com/nix-community/fenix/issues/123
+ #toolchain = fenix.packages.${buildSystem}.fromToolchainFile {
+ # file = ./rust-toolchain.toml;
+ # sha256 = "sha256-LU4C/i+maIOqBZagUaXpFyWZyOVfQ3Ah5/JTz7v6CG4=";
+ #};
+
+ fenixPkgs = fenix.packages.${buildSystem};
+
+ mkToolchain = fenixPkgs: fenixPkgs.toolchainOf {
+ # TODO change compiler to stable
+ channel = "1.77";
+ sha256 = "sha256-7QfkHty6hSrgNM0fspycYkRcB82eEqYa4CoAJ9qA3tU=";
};
- # ---- developpment shell, for making native builds only ----
- devShells =
- let
- shellWithPackages = (packages: (compile {
- inherit system git_version;
- pkgsSrc = nixpkgs;
- cargo2nixOverlay = cargo2nix.overlays.default;
- }).workspaceShell { inherit packages; });
- in
- {
- default = shellWithPackages
- (with pkgs; [
- rustfmt
- clang
- mold
- ]);
-
- # import the full shell using `nix develop .#full`
- full = shellWithPackages (with pkgs; [
- rustfmt
- rust-analyzer
- clang
- mold
- # ---- extra packages for dev tasks ----
- cargo-audit
- cargo-outdated
- cargo-machete
- nixpkgs-fmt
- ]);
+ toolchain = fenixPkgs.combine [
+ (mkToolchain fenixPkgs).rustc
+ (mkToolchain fenixPkgs).cargo
+ (mkToolchain fenixPkgs.targets.${rustTarget}).rust-std
+ ];
+
+ buildPackageAttrs = if
+ builtins.hasAttr "makeBuildPackageAttrs" buildTargets.${targetSystem}
+ then
+ buildTargets.${targetSystem}.makeBuildPackageAttrs pkgsCross
+ else
+ {};
+
+ naersk-lib = pkgs.callPackage naersk {
+ cargo = toolchain;
+ rustc = toolchain;
};
- });
+
+ in
+ naersk-lib.buildPackage (buildPackageAttrs // rec {
+ name = "garage";
+ pname = "garage";
+ src = ./.;
+ strictDeps = true;
+ doCheck = false;
+ release = false; # for now
+
+ # TODO co uld be removed ?
+ OPENSSL_STATIC = "1";
+ OPENSSL_LIB_DIR = "${pkgsCross.pkgsStatic.openssl.out}/lib";
+ OPENSSL_INCLUDE_DIR = "${pkgsCross.pkgsStatic.openssl.dev}/include";
+
+ # TODO co uld be removed ?
+ # Required because ring crate is special. This also seems to have
+ # fixed some issues with the x86_64-windows cross-compile :shrug:
+ TARGET_CC = "${pkgsCross.stdenv.cc}/bin/${pkgsCross.stdenv.cc.targetPrefix}cc";
+
+ CARGO_BUILD_TARGET = rustTarget;
+ CARGO_BUILD_RUSTFLAGS = [
+ "-C" "target-feature=+crt-static"
+
+ # -latomic is required to build openssl-sys for armv6l-linux, but
+ # it doesn't seem to hurt any other builds.
+ "-C" "link-args=-static -latomic"
+
+ # https://github.com/rust-lang/cargo/issues/4133
+ "-C" "linker=${TARGET_CC}"
+ ];
+ })
+ );
+ };
}