wip: build with crane
Some checks failed
ci/woodpecker/push/debug Pipeline failed

- cross compiling doesnt work (c compiler fails)
- default.nix and shell.nix are not updated
This commit is contained in:
Alex 2025-02-01 21:48:10 +01:00
parent 4dc2bc337f
commit 1127239215
3 changed files with 165 additions and 170 deletions

69
flake.lock generated
View file

@ -1,28 +1,17 @@
{ {
"nodes": { "nodes": {
"cargo2nix": { "crane": {
"inputs": {
"flake-compat": [
"flake-compat"
],
"flake-utils": "flake-utils",
"nixpkgs": [
"nixpkgs"
],
"rust-overlay": "rust-overlay"
},
"locked": { "locked": {
"lastModified": 1705129117, "lastModified": 1737689766,
"narHash": "sha256-LgdDHibvimzYhxBK3kxCk2gAL7k4Hyigl5KI0X9cijA=", "narHash": "sha256-ivVXYaYlShxYoKfSo5+y5930qMKKJ8CLcAoIBPQfJ6s=",
"owner": "cargo2nix", "owner": "ipetkov",
"repo": "cargo2nix", "repo": "crane",
"rev": "ae19a9e1f8f0880c088ea155ab66cee1fa001f59", "rev": "6fe74265bbb6d016d663b1091f015e2976c4a527",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "cargo2nix", "owner": "ipetkov",
"repo": "cargo2nix", "repo": "crane",
"rev": "ae19a9e1f8f0880c088ea155ab66cee1fa001f59",
"type": "github" "type": "github"
} }
}, },
@ -42,12 +31,15 @@
} }
}, },
"flake-utils": { "flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": { "locked": {
"lastModified": 1659877975, "lastModified": 1731533236,
"narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=", "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide", "owner": "numtide",
"repo": "flake-utils", "repo": "flake-utils",
"rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0", "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -74,34 +66,45 @@
}, },
"root": { "root": {
"inputs": { "inputs": {
"cargo2nix": "cargo2nix", "crane": "crane",
"flake-compat": "flake-compat", "flake-compat": "flake-compat",
"flake-utils": [ "flake-utils": "flake-utils",
"cargo2nix", "nixpkgs": "nixpkgs",
"flake-utils" "rust-overlay": "rust-overlay"
],
"nixpkgs": "nixpkgs"
} }
}, },
"rust-overlay": { "rust-overlay": {
"inputs": { "inputs": {
"nixpkgs": [ "nixpkgs": [
"cargo2nix",
"nixpkgs" "nixpkgs"
] ]
}, },
"locked": { "locked": {
"lastModified": 1736649126, "lastModified": 1738376888,
"narHash": "sha256-XCw5sv/ePsroqiF3lJM6Y2X9EhPdHeE47gr3Q8b0UQw=", "narHash": "sha256-S6ErHxkSm0iA7ZMsjjDaASWxbELYcdfv8BhOkkj1rHw=",
"owner": "oxalica", "owner": "oxalica",
"repo": "rust-overlay", "repo": "rust-overlay",
"rev": "162ab0edc2936508470199b2e8e6c444a2535019", "rev": "83284068670d5ae4a43641c4afb150f3446be70d",
"type": "github" "type": "github"
}, },
"original": { "original": {
"owner": "oxalica", "owner": "oxalica",
"repo": "rust-overlay", "repo": "rust-overlay",
"rev": "162ab0edc2936508470199b2e8e6c444a2535019", "type": "github"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github" "type": "github"
} }
} }

View file

@ -8,29 +8,14 @@
inputs.flake-compat.url = "github:nix-community/flake-compat"; inputs.flake-compat.url = "github:nix-community/flake-compat";
inputs.cargo2nix = { inputs.flake-utils.url = "github:numtide/flake-utils";
# 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: inputs.crane.url = "github:ipetkov/crane";
# - 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) inputs.rust-overlay.url = "github:oxalica/rust-overlay";
url = "github:cargo2nix/cargo2nix/ae19a9e1f8f0880c088ea155ab66cee1fa001f59"; inputs.rust-overlay.inputs.nixpkgs.follows = "nixpkgs";
# Rust overlay as of 2025-01-12 outputs = { self, nixpkgs, flake-utils, crane, rust-overlay, ... }:
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 let
git_version = self.lastModifiedDate; git_version = self.lastModifiedDate;
compile = import ./nix/compile.nix; compile = import ./nix/compile.nix;
@ -42,52 +27,48 @@
{ {
packages = packages =
let let
packageFor = target: (compile { packageFor = target: release: (compile {
inherit system git_version target; inherit system git_version target nixpkgs crane rust-overlay release;
pkgsSrc = nixpkgs; }).garage;
cargo2nixOverlay = cargo2nix.overlays.default;
release = true;
}).workspace.garage { compileMode = "build"; };
in in
{ {
# default = native release build # default = native release build
default = packageFor null; default = packageFor null true;
# other = cross-compiled, statically-linked builds # other = cross-compiled, statically-linked builds
amd64 = packageFor "x86_64-unknown-linux-musl"; amd64 = packageFor "x86_64-unknown-linux-musl" true;
i386 = packageFor "i686-unknown-linux-musl"; i386 = packageFor "i686-unknown-linux-musl" true;
arm64 = packageFor "aarch64-unknown-linux-musl"; arm64 = packageFor "aarch64-unknown-linux-musl" true;
arm = packageFor "armv6l-unknown-linux-musl"; arm = packageFor "armv6l-unknown-linux-musl" true;
# non-optimized packages
dev = packageFor null false;
dev-amd64 = packageFor "x86_64-unknown-linux-musl" false;
dev-i386 = packageFor "i686-unknown-linux-musl" false;
dev-arm64 = packageFor "aarch64-unknown-linux-musl" false;
dev-arm = packageFor "armv6l-unknown-linux-musl" false;
}; };
# ---- developpment shell, for making native builds only ---- # ---- developpment shell, for making native builds only ----
devShells = devShells =
let let
shellWithPackages = (packages: (compile { targets = compile {
inherit system git_version; inherit system git_version nixpkgs crane rust-overlay;
pkgsSrc = nixpkgs; };
cargo2nixOverlay = cargo2nix.overlays.default;
}).workspaceShell { inherit packages; });
in in
{ {
default = shellWithPackages default = targets.devShell;
(with pkgs; [
rustfmt
clang
mold
]);
# import the full shell using `nix develop .#full` # import the full shell using `nix develop .#full`
full = shellWithPackages (with pkgs; [ full = pkgs.mkShell {
rustfmt buildInputs = with pkgs; [
rust-analyzer targets.toolchain
clang
mold
# ---- extra packages for dev tasks ---- # ---- extra packages for dev tasks ----
rust-analyzer
cargo-audit cargo-audit
cargo-outdated cargo-outdated
cargo-machete cargo-machete
nixpkgs-fmt nixpkgs-fmt
]); ];
};
}; };
}); });
} }

View file

@ -1,83 +1,52 @@
{ system, target ? null, pkgsSrc, cargo2nixOverlay {
, release ? false, git_version ? null, features ? null, }: /* build inputs */
nixpkgs,
crane,
rust-overlay,
/* parameters */
system,
git_version ? "unknown",
target ? null,
release ? false,
features ? null,
}:
let let
log = v: builtins.trace v v; log = v: builtins.trace v v;
pkgs = if target != null then pkgs =
import pkgsSrc { import nixpkgs {
inherit system; inherit system;
crossSystem = { overlays = [ (import rust-overlay) ];
config = target;
isStatic = true;
};
overlays = [ cargo2nixOverlay ];
}
else
import pkgsSrc {
inherit system;
overlays = [ cargo2nixOverlay ];
}; };
toolchainOptions = { inherit (pkgs) lib;
rustVersion = "1.78.0";
extraRustComponents = [ "clippy" ];
};
/* Cargo2nix provides many overrides by default, you can take inspiration from them: toolchain = pkgs.symlinkJoin {
https://github.com/cargo2nix/cargo2nix/blob/master/overlay/overrides.nix name = "garage-rust-toolchain-1.78";
paths = [
You can have a complete list of the available options by looking at the overriden object, mkcrate: (pkgs.rust-bin.stable."1.78.0".default.override {
https://github.com/cargo2nix/cargo2nix/blob/master/overlay/mkcrate.nix targets = [
*/ "arm-unknown-linux-musleabihf"
packageOverrides = pkgs: "aarch64-unknown-linux-musl"
pkgs.rustBuilder.overrides.all ++ [ "i686-unknown-linux-musl"
/* [1] We need to alter Nix hardening to make static binaries: PIE, "x86_64-unknown-linux-musl"
Position Independent Executables seems to be supported only on amd64. Having
this flag set either 1. make our executables crash or 2. compile as dynamic on some platforms.
Here, we deactivate it. Later (find `codegenOpts`), we reactivate it for supported targets
(only amd64 curently) through the `-static-pie` flag.
PIE is a feature used by ASLR, which helps mitigate security issues.
Learn more about Nix Hardening at: https://github.com/NixOS/nixpkgs/blob/master/pkgs/build-support/cc-wrapper/add-hardening.sh
[2] We want to inject the git version while keeping the build deterministic.
As we do not want to consider the .git folder as part of the input source,
we ask the user (the CI often) to pass the value to Nix.
[3] We don't want libsodium-sys and zstd-sys to try to use pkgconfig to build against a system library.
However the features to do so get activated for some reason (due to a bug in cargo2nix?),
so disable them manually here.
*/
(pkgs.rustBuilder.rustLib.makeOverride {
name = "garage";
overrideAttrs = drv:
(if git_version != null then {
# [2]
preConfigure = ''
${drv.preConfigure or ""}
export GIT_VERSION="${git_version}"
'';
} else
{ }) // {
# [1]
hardeningDisable = [ "pie" ];
};
})
(pkgs.rustBuilder.rustLib.makeOverride {
name = "libsodium-sys";
overrideArgs = old: {
features = [ ]; # [3]
};
})
(pkgs.rustBuilder.rustLib.makeOverride {
name = "zstd-sys";
overrideArgs = old: {
features = [ ]; # [3]
};
})
]; ];
extensions = [
"rust-src"
"rustfmt"
];
})
pkgs.clang
pkgs.mold
pkgs.protobuf
];
};
craneLib = (crane.mkLib pkgs).overrideToolchain toolchain;
src = craneLib.cleanCargoSource ../.;
/* We ship some parts of the code disabled by default by putting them behind a flag. /* We ship some parts of the code disabled by default by putting them behind a flag.
It speeds up the compilation (when the feature is not required) and released crates have less dependency by default (less attack surface, disk space, etc.). It speeds up the compilation (when the feature is not required) and released crates have less dependency by default (less attack surface, disk space, etc.).
@ -87,16 +56,16 @@ let
rootFeatures = if features != null then rootFeatures = if features != null then
features features
else else
([ "garage/bundled-libs" "garage/lmdb" "garage/sqlite" "garage/k2v" ] ++ (if release then [ ([ "bundled-libs" "lmdb" "sqlite" "k2v" ] ++ (if release then [
"garage/consul-discovery" "consul-discovery"
"garage/kubernetes-discovery" "kubernetes-discovery"
"garage/metrics" "metrics"
"garage/telemetry-otlp" "telemetry-otlp"
"garage/syslog" "syslog"
] else ] else
[ ])); [ ]));
packageFun = import ../Cargo.nix; featuresStr = lib.concatStringsSep "," rootFeatures;
/* We compile fully static binaries with musl to simplify deployment on most systems. /* We compile fully static binaries with musl to simplify deployment on most systems.
When possible, we reactivate PIE hardening (see above). When possible, we reactivate PIE hardening (see above).
@ -107,8 +76,7 @@ let
For more information on static builds, please refer to Rust's RFC 1721. For more information on static builds, please refer to Rust's RFC 1721.
https://rust-lang.github.io/rfcs/1721-crt-static.html#specifying-dynamicstatic-c-runtime-linkage https://rust-lang.github.io/rfcs/1721-crt-static.html#specifying-dynamicstatic-c-runtime-linkage
*/ */
codegenOptsMap = {
codegenOpts = {
"armv6l-unknown-linux-musleabihf" = [ "armv6l-unknown-linux-musleabihf" = [
"target-feature=+crt-static" "target-feature=+crt-static"
"link-arg=-static" "link-arg=-static"
@ -131,8 +99,51 @@ let
else else
target; target;
in pkgs.rustBuilder.makePackageSet ({ codegenOpts = if target != null then codegenOptsMap.${target} else [
inherit release packageFun packageOverrides codegenOpts rootFeatures; "link-args=-fuse-ld=mold"
target = rustTarget; ];
workspaceSrc = pkgs.lib.cleanSource ../.;
} // toolchainOptions) commonArgs =
{
inherit src;
pname = "garage";
version = git_version;
strictDeps = true;
cargoExtraArgs = "--features ${featuresStr}";
GIT_VERSION = git_version;
CARGO_PROFILE = if release then "release" else "dev";
CARGO_BUILD_RUSTFLAGS =
lib.concatStringsSep
" "
(builtins.map (flag: "-C ${flag}") codegenOpts);
}
//
(if rustTarget != null then {
CARGO_BUILD_TARGET = rustTarget;
} else {});
in rec {
inherit toolchain;
devShell = pkgs.mkShell {
buildInputs = [
toolchain
];
};
garage-deps = craneLib.buildDepsOnly commonArgs;
garage = craneLib.buildPackage (commonArgs // {
cargoArtifacts = garage-deps;
doCheck = false;
});
garage-test = craneLib.cargoTest (commonArgs // {
cargoTestExtraArgs = "--workspace";
cargoArtifacts = garage;
CARGO_PROFILE = "test";
});
}